diff options
author | Paul Mundt <lethal@linux-sh.org> | 2011-01-13 01:06:28 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2011-01-13 01:06:28 -0500 |
commit | f43dc23d5ea91fca257be02138a255f02d98e806 (patch) | |
tree | b29722f6e965316e90ac97abf79923ced250dc21 /drivers/serial | |
parent | f8e53553f452dcbf67cb89c8cba63a1cd6eb4cc0 (diff) | |
parent | 4162cf64973df51fc885825bc9ca4d055891c49f (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6 into common/serial-rework
Conflicts:
arch/sh/kernel/cpu/sh2/setup-sh7619.c
arch/sh/kernel/cpu/sh2a/setup-mxg.c
arch/sh/kernel/cpu/sh2a/setup-sh7201.c
arch/sh/kernel/cpu/sh2a/setup-sh7203.c
arch/sh/kernel/cpu/sh2a/setup-sh7206.c
arch/sh/kernel/cpu/sh3/setup-sh7705.c
arch/sh/kernel/cpu/sh3/setup-sh770x.c
arch/sh/kernel/cpu/sh3/setup-sh7710.c
arch/sh/kernel/cpu/sh3/setup-sh7720.c
arch/sh/kernel/cpu/sh4/setup-sh4-202.c
arch/sh/kernel/cpu/sh4/setup-sh7750.c
arch/sh/kernel/cpu/sh4/setup-sh7760.c
arch/sh/kernel/cpu/sh4a/setup-sh7343.c
arch/sh/kernel/cpu/sh4a/setup-sh7366.c
arch/sh/kernel/cpu/sh4a/setup-sh7722.c
arch/sh/kernel/cpu/sh4a/setup-sh7723.c
arch/sh/kernel/cpu/sh4a/setup-sh7724.c
arch/sh/kernel/cpu/sh4a/setup-sh7763.c
arch/sh/kernel/cpu/sh4a/setup-sh7770.c
arch/sh/kernel/cpu/sh4a/setup-sh7780.c
arch/sh/kernel/cpu/sh4a/setup-sh7785.c
arch/sh/kernel/cpu/sh4a/setup-sh7786.c
arch/sh/kernel/cpu/sh4a/setup-shx3.c
arch/sh/kernel/cpu/sh5/setup-sh5.c
drivers/serial/sh-sci.c
drivers/serial/sh-sci.h
include/linux/serial_sci.h
Diffstat (limited to 'drivers/serial')
98 files changed, 18737 insertions, 3194 deletions
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c index cb6d85d7ff43..d89aa38c5cf0 100644 --- a/drivers/serial/21285.c +++ b/drivers/serial/21285.c | |||
@@ -58,7 +58,7 @@ static const char serial21285_name[] = "Footbridge UART"; | |||
58 | static void serial21285_stop_tx(struct uart_port *port) | 58 | static void serial21285_stop_tx(struct uart_port *port) |
59 | { | 59 | { |
60 | if (tx_enabled(port)) { | 60 | if (tx_enabled(port)) { |
61 | disable_irq(IRQ_CONTX); | 61 | disable_irq_nosync(IRQ_CONTX); |
62 | tx_enabled(port) = 0; | 62 | tx_enabled(port) = 0; |
63 | } | 63 | } |
64 | } | 64 | } |
@@ -74,7 +74,7 @@ static void serial21285_start_tx(struct uart_port *port) | |||
74 | static void serial21285_stop_rx(struct uart_port *port) | 74 | static void serial21285_stop_rx(struct uart_port *port) |
75 | { | 75 | { |
76 | if (rx_enabled(port)) { | 76 | if (rx_enabled(port)) { |
77 | disable_irq(IRQ_CONRX); | 77 | disable_irq_nosync(IRQ_CONRX); |
78 | rx_enabled(port) = 0; | 78 | rx_enabled(port) = 0; |
79 | } | 79 | } |
80 | } | 80 | } |
@@ -86,7 +86,7 @@ static void serial21285_enable_ms(struct uart_port *port) | |||
86 | static irqreturn_t serial21285_rx_chars(int irq, void *dev_id) | 86 | static irqreturn_t serial21285_rx_chars(int irq, void *dev_id) |
87 | { | 87 | { |
88 | struct uart_port *port = dev_id; | 88 | struct uart_port *port = dev_id; |
89 | struct tty_struct *tty = port->info->port.tty; | 89 | struct tty_struct *tty = port->state->port.tty; |
90 | unsigned int status, ch, flag, rxs, max_count = 256; | 90 | unsigned int status, ch, flag, rxs, max_count = 256; |
91 | 91 | ||
92 | status = *CSR_UARTFLG; | 92 | status = *CSR_UARTFLG; |
@@ -124,7 +124,7 @@ static irqreturn_t serial21285_rx_chars(int irq, void *dev_id) | |||
124 | static irqreturn_t serial21285_tx_chars(int irq, void *dev_id) | 124 | static irqreturn_t serial21285_tx_chars(int irq, void *dev_id) |
125 | { | 125 | { |
126 | struct uart_port *port = dev_id; | 126 | struct uart_port *port = dev_id; |
127 | struct circ_buf *xmit = &port->info->xmit; | 127 | struct circ_buf *xmit = &port->state->xmit; |
128 | int count = 256; | 128 | int count = 256; |
129 | 129 | ||
130 | if (port->x_char) { | 130 | if (port->x_char) { |
@@ -216,7 +216,7 @@ serial21285_set_termios(struct uart_port *port, struct ktermios *termios, | |||
216 | struct ktermios *old) | 216 | struct ktermios *old) |
217 | { | 217 | { |
218 | unsigned long flags; | 218 | unsigned long flags; |
219 | unsigned int baud, quot, h_lcr; | 219 | unsigned int baud, quot, h_lcr, b; |
220 | 220 | ||
221 | /* | 221 | /* |
222 | * We don't support modem control lines. | 222 | * We don't support modem control lines. |
@@ -234,12 +234,8 @@ serial21285_set_termios(struct uart_port *port, struct ktermios *termios, | |||
234 | */ | 234 | */ |
235 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); | 235 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); |
236 | quot = uart_get_divisor(port, baud); | 236 | quot = uart_get_divisor(port, baud); |
237 | 237 | b = port->uartclk / (16 * quot); | |
238 | if (port->info && port->info->port.tty) { | 238 | tty_termios_encode_baud_rate(termios, b, b); |
239 | struct tty_struct *tty = port->info->port.tty; | ||
240 | unsigned int b = port->uartclk / (16 * quot); | ||
241 | tty_encode_baud_rate(tty, b, b); | ||
242 | } | ||
243 | 239 | ||
244 | switch (termios->c_cflag & CSIZE) { | 240 | switch (termios->c_cflag & CSIZE) { |
245 | case CS5: | 241 | case CS5: |
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c index d935b2d04f93..be0ebce36e54 100644 --- a/drivers/serial/68328serial.c +++ b/drivers/serial/68328serial.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/pm.h> | 35 | #include <linux/pm.h> |
36 | #include <linux/bitops.h> | 36 | #include <linux/bitops.h> |
37 | #include <linux/delay.h> | 37 | #include <linux/delay.h> |
38 | #include <linux/gfp.h> | ||
38 | 39 | ||
39 | #include <asm/io.h> | 40 | #include <asm/io.h> |
40 | #include <asm/irq.h> | 41 | #include <asm/irq.h> |
@@ -77,10 +78,6 @@ struct m68k_serial *m68k_consinfo = 0; | |||
77 | 78 | ||
78 | #define M68K_CLOCK (16667000) /* FIXME: 16MHz is likely wrong */ | 79 | #define M68K_CLOCK (16667000) /* FIXME: 16MHz is likely wrong */ |
79 | 80 | ||
80 | #ifdef CONFIG_CONSOLE | ||
81 | extern wait_queue_head_t keypress_wait; | ||
82 | #endif | ||
83 | |||
84 | struct tty_driver *serial_driver; | 81 | struct tty_driver *serial_driver; |
85 | 82 | ||
86 | /* number of characters left in xmit buffer before we ask for more */ | 83 | /* number of characters left in xmit buffer before we ask for more */ |
@@ -101,19 +98,13 @@ static void change_speed(struct m68k_serial *info); | |||
101 | * Setup for console. Argument comes from the boot command line. | 98 | * Setup for console. Argument comes from the boot command line. |
102 | */ | 99 | */ |
103 | 100 | ||
104 | #if defined(CONFIG_M68EZ328ADS) || defined(CONFIG_ALMA_ANS) || defined(CONFIG_DRAGONIXVZ) | 101 | /* note: this is messy, but it works, again, perhaps defined somewhere else?*/ |
105 | #define CONSOLE_BAUD_RATE 115200 | 102 | #ifdef CONFIG_M68VZ328 |
106 | #define DEFAULT_CBAUD B115200 | 103 | #define CONSOLE_BAUD_RATE 19200 |
107 | #else | 104 | #define DEFAULT_CBAUD B19200 |
108 | /* (es) */ | ||
109 | /* note: this is messy, but it works, again, perhaps defined somewhere else?*/ | ||
110 | #ifdef CONFIG_M68VZ328 | ||
111 | #define CONSOLE_BAUD_RATE 19200 | ||
112 | #define DEFAULT_CBAUD B19200 | ||
113 | #endif | ||
114 | /* (/es) */ | ||
115 | #endif | 105 | #endif |
116 | 106 | ||
107 | |||
117 | #ifndef CONSOLE_BAUD_RATE | 108 | #ifndef CONSOLE_BAUD_RATE |
118 | #define CONSOLE_BAUD_RATE 9600 | 109 | #define CONSOLE_BAUD_RATE 9600 |
119 | #define DEFAULT_CBAUD B9600 | 110 | #define DEFAULT_CBAUD B9600 |
@@ -153,8 +144,6 @@ static int baud_table[] = { | |||
153 | 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, | 144 | 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, |
154 | 9600, 19200, 38400, 57600, 115200, 0 }; | 145 | 9600, 19200, 38400, 57600, 115200, 0 }; |
155 | 146 | ||
156 | #define BAUD_TABLE_SIZE (sizeof(baud_table)/sizeof(baud_table[0])) | ||
157 | |||
158 | /* Sets or clears DTR/RTS on the requested line */ | 147 | /* Sets or clears DTR/RTS on the requested line */ |
159 | static inline void m68k_rtsdtr(struct m68k_serial *ss, int set) | 148 | static inline void m68k_rtsdtr(struct m68k_serial *ss, int set) |
160 | { | 149 | { |
@@ -301,10 +290,6 @@ static void receive_chars(struct m68k_serial *info, unsigned short rx) | |||
301 | return; | 290 | return; |
302 | #endif /* CONFIG_MAGIC_SYSRQ */ | 291 | #endif /* CONFIG_MAGIC_SYSRQ */ |
303 | } | 292 | } |
304 | /* It is a 'keyboard interrupt' ;-) */ | ||
305 | #ifdef CONFIG_CONSOLE | ||
306 | wake_up(&keypress_wait); | ||
307 | #endif | ||
308 | } | 293 | } |
309 | 294 | ||
310 | if(!tty) | 295 | if(!tty) |
@@ -884,7 +869,9 @@ static int get_serial_info(struct m68k_serial * info, | |||
884 | tmp.close_delay = info->close_delay; | 869 | tmp.close_delay = info->close_delay; |
885 | tmp.closing_wait = info->closing_wait; | 870 | tmp.closing_wait = info->closing_wait; |
886 | tmp.custom_divisor = info->custom_divisor; | 871 | tmp.custom_divisor = info->custom_divisor; |
887 | copy_to_user(retinfo,&tmp,sizeof(*retinfo)); | 872 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) |
873 | return -EFAULT; | ||
874 | |||
888 | return 0; | 875 | return 0; |
889 | } | 876 | } |
890 | 877 | ||
@@ -897,7 +884,8 @@ static int set_serial_info(struct m68k_serial * info, | |||
897 | 884 | ||
898 | if (!new_info) | 885 | if (!new_info) |
899 | return -EFAULT; | 886 | return -EFAULT; |
900 | copy_from_user(&new_serial,new_info,sizeof(new_serial)); | 887 | if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) |
888 | return -EFAULT; | ||
901 | old_info = *info; | 889 | old_info = *info; |
902 | 890 | ||
903 | if (!capable(CAP_SYS_ADMIN)) { | 891 | if (!capable(CAP_SYS_ADMIN)) { |
@@ -958,8 +946,7 @@ static int get_lsr_info(struct m68k_serial * info, unsigned int *value) | |||
958 | status = 0; | 946 | status = 0; |
959 | #endif | 947 | #endif |
960 | local_irq_restore(flags); | 948 | local_irq_restore(flags); |
961 | put_user(status,value); | 949 | return put_user(status, value); |
962 | return 0; | ||
963 | } | 950 | } |
964 | 951 | ||
965 | /* | 952 | /* |
@@ -1014,27 +1001,18 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, | |||
1014 | send_break(info, arg ? arg*(100) : 250); | 1001 | send_break(info, arg ? arg*(100) : 250); |
1015 | return 0; | 1002 | return 0; |
1016 | case TIOCGSERIAL: | 1003 | case TIOCGSERIAL: |
1017 | if (access_ok(VERIFY_WRITE, (void *) arg, | 1004 | return get_serial_info(info, |
1018 | sizeof(struct serial_struct))) | 1005 | (struct serial_struct *) arg); |
1019 | return get_serial_info(info, | ||
1020 | (struct serial_struct *) arg); | ||
1021 | return -EFAULT; | ||
1022 | case TIOCSSERIAL: | 1006 | case TIOCSSERIAL: |
1023 | return set_serial_info(info, | 1007 | return set_serial_info(info, |
1024 | (struct serial_struct *) arg); | 1008 | (struct serial_struct *) arg); |
1025 | case TIOCSERGETLSR: /* Get line status register */ | 1009 | case TIOCSERGETLSR: /* Get line status register */ |
1026 | if (access_ok(VERIFY_WRITE, (void *) arg, | 1010 | return get_lsr_info(info, (unsigned int *) arg); |
1027 | sizeof(unsigned int))) | ||
1028 | return get_lsr_info(info, (unsigned int *) arg); | ||
1029 | return -EFAULT; | ||
1030 | case TIOCSERGSTRUCT: | 1011 | case TIOCSERGSTRUCT: |
1031 | if (!access_ok(VERIFY_WRITE, (void *) arg, | 1012 | if (copy_to_user((struct m68k_serial *) arg, |
1032 | sizeof(struct m68k_serial))) | 1013 | info, sizeof(struct m68k_serial))) |
1033 | return -EFAULT; | 1014 | return -EFAULT; |
1034 | copy_to_user((struct m68k_serial *) arg, | ||
1035 | info, sizeof(struct m68k_serial)); | ||
1036 | return 0; | 1015 | return 0; |
1037 | |||
1038 | default: | 1016 | default: |
1039 | return -ENOIOCTLCMD; | 1017 | return -ENOIOCTLCMD; |
1040 | } | 1018 | } |
@@ -1244,7 +1222,9 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
1244 | retval = -ERESTARTSYS; | 1222 | retval = -ERESTARTSYS; |
1245 | break; | 1223 | break; |
1246 | } | 1224 | } |
1225 | tty_unlock(); | ||
1247 | schedule(); | 1226 | schedule(); |
1227 | tty_lock(); | ||
1248 | } | 1228 | } |
1249 | current->state = TASK_RUNNING; | 1229 | current->state = TASK_RUNNING; |
1250 | remove_wait_queue(&info->open_wait, &wait); | 1230 | remove_wait_queue(&info->open_wait, &wait); |
@@ -1406,10 +1386,10 @@ static void m68328_set_baud(void) | |||
1406 | USTCNT = ustcnt & ~USTCNT_TXEN; | 1386 | USTCNT = ustcnt & ~USTCNT_TXEN; |
1407 | 1387 | ||
1408 | again: | 1388 | again: |
1409 | for (i = 0; i < sizeof(baud_table) / sizeof(baud_table[0]); i++) | 1389 | for (i = 0; i < ARRAY_SIZE(baud_table); i++) |
1410 | if (baud_table[i] == m68328_console_baud) | 1390 | if (baud_table[i] == m68328_console_baud) |
1411 | break; | 1391 | break; |
1412 | if (i >= sizeof(baud_table) / sizeof(baud_table[0])) { | 1392 | if (i >= ARRAY_SIZE(baud_table)) { |
1413 | m68328_console_baud = 9600; | 1393 | m68328_console_baud = 9600; |
1414 | goto again; | 1394 | goto again; |
1415 | } | 1395 | } |
@@ -1435,10 +1415,10 @@ int m68328_console_setup(struct console *cp, char *arg) | |||
1435 | if (arg) | 1415 | if (arg) |
1436 | n = simple_strtoul(arg,NULL,0); | 1416 | n = simple_strtoul(arg,NULL,0); |
1437 | 1417 | ||
1438 | for (i = 0; i < BAUD_TABLE_SIZE; i++) | 1418 | for (i = 0; i < ARRAY_SIZE(baud_table); i++) |
1439 | if (baud_table[i] == n) | 1419 | if (baud_table[i] == n) |
1440 | break; | 1420 | break; |
1441 | if (i < BAUD_TABLE_SIZE) { | 1421 | if (i < ARRAY_SIZE(baud_table)) { |
1442 | m68328_console_baud = n; | 1422 | m68328_console_baud = n; |
1443 | m68328_console_cbaud = 0; | 1423 | m68328_console_cbaud = 0; |
1444 | if (i > 15) { | 1424 | if (i > 15) { |
diff --git a/drivers/serial/68328serial.h b/drivers/serial/68328serial.h index 58aa2154655b..664ceb0a158c 100644 --- a/drivers/serial/68328serial.h +++ b/drivers/serial/68328serial.h | |||
@@ -181,13 +181,8 @@ struct m68k_serial { | |||
181 | /* | 181 | /* |
182 | * Define the number of ports supported and their irqs. | 182 | * Define the number of ports supported and their irqs. |
183 | */ | 183 | */ |
184 | #ifndef CONFIG_68328_SERIAL_UART2 | ||
185 | #define NR_PORTS 1 | 184 | #define NR_PORTS 1 |
186 | #define UART_IRQ_DEFNS {UART_IRQ_NUM} | 185 | #define UART_IRQ_DEFNS {UART_IRQ_NUM} |
187 | #else | ||
188 | #define NR_PORTS 2 | ||
189 | #define UART_IRQ_DEFNS {UART1_IRQ_NUM, UART2_IRQ_NUM} | ||
190 | #endif | ||
191 | 186 | ||
192 | #endif /* __KERNEL__ */ | 187 | #endif /* __KERNEL__ */ |
193 | #endif /* !(_MC683XX_SERIAL_H) */ | 188 | #endif /* !(_MC683XX_SERIAL_H) */ |
diff --git a/drivers/serial/68360serial.c b/drivers/serial/68360serial.c index 24661cd5e4fb..88b13356ec10 100644 --- a/drivers/serial/68360serial.c +++ b/drivers/serial/68360serial.c | |||
@@ -1381,6 +1381,30 @@ static void send_break(ser_info_t *info, unsigned int duration) | |||
1381 | } | 1381 | } |
1382 | 1382 | ||
1383 | 1383 | ||
1384 | /* | ||
1385 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) | ||
1386 | * Return: write counters to the user passed counter struct | ||
1387 | * NB: both 1->0 and 0->1 transitions are counted except for | ||
1388 | * RI where only 0->1 is counted. | ||
1389 | */ | ||
1390 | static int rs_360_get_icount(struct tty_struct *tty, | ||
1391 | struct serial_icounter_struct *icount) | ||
1392 | { | ||
1393 | ser_info_t *info = (ser_info_t *)tty->driver_data; | ||
1394 | struct async_icount cnow; | ||
1395 | |||
1396 | local_irq_disable(); | ||
1397 | cnow = info->state->icount; | ||
1398 | local_irq_enable(); | ||
1399 | |||
1400 | icount->cts = cnow.cts; | ||
1401 | icount->dsr = cnow.dsr; | ||
1402 | icount->rng = cnow.rng; | ||
1403 | icount->dcd = cnow.dcd; | ||
1404 | |||
1405 | return 0; | ||
1406 | } | ||
1407 | |||
1384 | static int rs_360_ioctl(struct tty_struct *tty, struct file * file, | 1408 | static int rs_360_ioctl(struct tty_struct *tty, struct file * file, |
1385 | unsigned int cmd, unsigned long arg) | 1409 | unsigned int cmd, unsigned long arg) |
1386 | { | 1410 | { |
@@ -1394,7 +1418,7 @@ static int rs_360_ioctl(struct tty_struct *tty, struct file * file, | |||
1394 | if (serial_paranoia_check(info, tty->name, "rs_ioctl")) | 1418 | if (serial_paranoia_check(info, tty->name, "rs_ioctl")) |
1395 | return -ENODEV; | 1419 | return -ENODEV; |
1396 | 1420 | ||
1397 | if ((cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { | 1421 | if (cmd != TIOCMIWAIT) { |
1398 | if (tty->flags & (1 << TTY_IO_ERROR)) | 1422 | if (tty->flags & (1 << TTY_IO_ERROR)) |
1399 | return -EIO; | 1423 | return -EIO; |
1400 | } | 1424 | } |
@@ -1477,31 +1501,6 @@ static int rs_360_ioctl(struct tty_struct *tty, struct file * file, | |||
1477 | return 0; | 1501 | return 0; |
1478 | #endif | 1502 | #endif |
1479 | 1503 | ||
1480 | /* | ||
1481 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) | ||
1482 | * Return: write counters to the user passed counter struct | ||
1483 | * NB: both 1->0 and 0->1 transitions are counted except for | ||
1484 | * RI where only 0->1 is counted. | ||
1485 | */ | ||
1486 | case TIOCGICOUNT: | ||
1487 | local_irq_disable(); | ||
1488 | cnow = info->state->icount; | ||
1489 | local_irq_enable(); | ||
1490 | p_cuser = (struct serial_icounter_struct *) arg; | ||
1491 | /* error = put_user(cnow.cts, &p_cuser->cts); */ | ||
1492 | /* if (error) return error; */ | ||
1493 | /* error = put_user(cnow.dsr, &p_cuser->dsr); */ | ||
1494 | /* if (error) return error; */ | ||
1495 | /* error = put_user(cnow.rng, &p_cuser->rng); */ | ||
1496 | /* if (error) return error; */ | ||
1497 | /* error = put_user(cnow.dcd, &p_cuser->dcd); */ | ||
1498 | /* if (error) return error; */ | ||
1499 | |||
1500 | put_user(cnow.cts, &p_cuser->cts); | ||
1501 | put_user(cnow.dsr, &p_cuser->dsr); | ||
1502 | put_user(cnow.rng, &p_cuser->rng); | ||
1503 | put_user(cnow.dcd, &p_cuser->dcd); | ||
1504 | return 0; | ||
1505 | 1504 | ||
1506 | default: | 1505 | default: |
1507 | return -ENOIOCTLCMD; | 1506 | return -ENOIOCTLCMD; |
@@ -1705,7 +1704,6 @@ static void rs_360_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1705 | printk("jiff=%lu...", jiffies); | 1704 | printk("jiff=%lu...", jiffies); |
1706 | #endif | 1705 | #endif |
1707 | 1706 | ||
1708 | lock_kernel(); | ||
1709 | /* We go through the loop at least once because we can't tell | 1707 | /* We go through the loop at least once because we can't tell |
1710 | * exactly when the last character exits the shifter. There can | 1708 | * exactly when the last character exits the shifter. There can |
1711 | * be at least two characters waiting to be sent after the buffers | 1709 | * be at least two characters waiting to be sent after the buffers |
@@ -1734,7 +1732,6 @@ static void rs_360_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1734 | bdp--; | 1732 | bdp--; |
1735 | } while (bdp->status & BD_SC_READY); | 1733 | } while (bdp->status & BD_SC_READY); |
1736 | current->state = TASK_RUNNING; | 1734 | current->state = TASK_RUNNING; |
1737 | unlock_kernel(); | ||
1738 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT | 1735 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT |
1739 | printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); | 1736 | printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); |
1740 | #endif | 1737 | #endif |
@@ -1862,7 +1859,9 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
1862 | printk("block_til_ready blocking: ttys%d, count = %d\n", | 1859 | printk("block_til_ready blocking: ttys%d, count = %d\n", |
1863 | info->line, state->count); | 1860 | info->line, state->count); |
1864 | #endif | 1861 | #endif |
1862 | tty_unlock(); | ||
1865 | schedule(); | 1863 | schedule(); |
1864 | tty_lock(); | ||
1866 | } | 1865 | } |
1867 | current->state = TASK_RUNNING; | 1866 | current->state = TASK_RUNNING; |
1868 | remove_wait_queue(&info->open_wait, &wait); | 1867 | remove_wait_queue(&info->open_wait, &wait); |
@@ -2649,7 +2648,7 @@ static int __init rs_360_init(void) | |||
2649 | sup->tfcr = SMC_EB; | 2648 | sup->tfcr = SMC_EB; |
2650 | 2649 | ||
2651 | /* Set this to 1 for now, so we get single | 2650 | /* Set this to 1 for now, so we get single |
2652 | * character interrupts. Using idle charater | 2651 | * character interrupts. Using idle character |
2653 | * time requires some additional tuning. | 2652 | * time requires some additional tuning. |
2654 | */ | 2653 | */ |
2655 | sup->mrblr = 1; | 2654 | sup->mrblr = 1; |
@@ -2728,7 +2727,7 @@ static int __init rs_360_init(void) | |||
2728 | up->tfcr = SMC_EB; | 2727 | up->tfcr = SMC_EB; |
2729 | 2728 | ||
2730 | /* Set this to 1 for now, so we get single | 2729 | /* Set this to 1 for now, so we get single |
2731 | * character interrupts. Using idle charater | 2730 | * character interrupts. Using idle character |
2732 | * time requires some additional tuning. | 2731 | * time requires some additional tuning. |
2733 | */ | 2732 | */ |
2734 | up->mrblr = 1; | 2733 | up->mrblr = 1; |
@@ -2886,7 +2885,7 @@ int serial_console_setup( struct console *co, char *options) | |||
2886 | sup->tfcr = SMC_EB; | 2885 | sup->tfcr = SMC_EB; |
2887 | 2886 | ||
2888 | /* Set this to 1 for now, so we get single | 2887 | /* Set this to 1 for now, so we get single |
2889 | * character interrupts. Using idle charater | 2888 | * character interrupts. Using idle character |
2890 | * time requires some additional tuning. | 2889 | * time requires some additional tuning. |
2891 | */ | 2890 | */ |
2892 | sup->mrblr = 1; | 2891 | sup->mrblr = 1; |
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index fb867a9f55e9..b25e6e490530 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
32 | #include <linux/platform_device.h> | 32 | #include <linux/platform_device.h> |
33 | #include <linux/tty.h> | 33 | #include <linux/tty.h> |
34 | #include <linux/ratelimit.h> | ||
34 | #include <linux/tty_flip.h> | 35 | #include <linux/tty_flip.h> |
35 | #include <linux/serial_reg.h> | 36 | #include <linux/serial_reg.h> |
36 | #include <linux/serial_core.h> | 37 | #include <linux/serial_core.h> |
@@ -38,6 +39,7 @@ | |||
38 | #include <linux/serial_8250.h> | 39 | #include <linux/serial_8250.h> |
39 | #include <linux/nmi.h> | 40 | #include <linux/nmi.h> |
40 | #include <linux/mutex.h> | 41 | #include <linux/mutex.h> |
42 | #include <linux/slab.h> | ||
41 | 43 | ||
42 | #include <asm/io.h> | 44 | #include <asm/io.h> |
43 | #include <asm/irq.h> | 45 | #include <asm/irq.h> |
@@ -64,6 +66,8 @@ static int serial_index(struct uart_port *port) | |||
64 | return (serial8250_reg.minor - 64) + port->line; | 66 | return (serial8250_reg.minor - 64) + port->line; |
65 | } | 67 | } |
66 | 68 | ||
69 | static unsigned int skip_txen_test; /* force skip of txen test at init time */ | ||
70 | |||
67 | /* | 71 | /* |
68 | * Debugging. | 72 | * Debugging. |
69 | */ | 73 | */ |
@@ -81,6 +85,9 @@ static int serial_index(struct uart_port *port) | |||
81 | 85 | ||
82 | #define PASS_LIMIT 256 | 86 | #define PASS_LIMIT 256 |
83 | 87 | ||
88 | #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) | ||
89 | |||
90 | |||
84 | /* | 91 | /* |
85 | * We default to IRQ0 for the "no irq" hack. Some | 92 | * We default to IRQ0 for the "no irq" hack. Some |
86 | * machine types want others as well - they're free | 93 | * machine types want others as well - they're free |
@@ -148,12 +155,6 @@ struct uart_8250_port { | |||
148 | unsigned char lsr_saved_flags; | 155 | unsigned char lsr_saved_flags; |
149 | #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA | 156 | #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA |
150 | unsigned char msr_saved_flags; | 157 | unsigned char msr_saved_flags; |
151 | |||
152 | /* | ||
153 | * We provide a per-port pm hook. | ||
154 | */ | ||
155 | void (*pm)(struct uart_port *port, | ||
156 | unsigned int state, unsigned int old); | ||
157 | }; | 158 | }; |
158 | 159 | ||
159 | struct irq_info { | 160 | struct irq_info { |
@@ -235,7 +236,7 @@ static const struct serial8250_config uart_config[] = { | |||
235 | .fifo_size = 128, | 236 | .fifo_size = 128, |
236 | .tx_loadsz = 128, | 237 | .tx_loadsz = 128, |
237 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | 238 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, |
238 | .flags = UART_CAP_FIFO, | 239 | .flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, |
239 | }, | 240 | }, |
240 | [PORT_16654] = { | 241 | [PORT_16654] = { |
241 | .name = "ST16654", | 242 | .name = "ST16654", |
@@ -294,9 +295,16 @@ static const struct serial8250_config uart_config[] = { | |||
294 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00, | 295 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00, |
295 | .flags = UART_CAP_FIFO | UART_CAP_AFE, | 296 | .flags = UART_CAP_FIFO | UART_CAP_AFE, |
296 | }, | 297 | }, |
298 | [PORT_U6_16550A] = { | ||
299 | .name = "U6_16550A", | ||
300 | .fifo_size = 64, | ||
301 | .tx_loadsz = 64, | ||
302 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | ||
303 | .flags = UART_CAP_FIFO | UART_CAP_AFE, | ||
304 | }, | ||
297 | }; | 305 | }; |
298 | 306 | ||
299 | #if defined (CONFIG_SERIAL_8250_AU1X00) | 307 | #if defined(CONFIG_MIPS_ALCHEMY) |
300 | 308 | ||
301 | /* Au1x00 UART hardware has a weird register layout */ | 309 | /* Au1x00 UART hardware has a weird register layout */ |
302 | static const u8 au_io_in_map[] = { | 310 | static const u8 au_io_in_map[] = { |
@@ -416,7 +424,6 @@ static unsigned int mem32_serial_in(struct uart_port *p, int offset) | |||
416 | return readl(p->membase + offset); | 424 | return readl(p->membase + offset); |
417 | } | 425 | } |
418 | 426 | ||
419 | #ifdef CONFIG_SERIAL_8250_AU1X00 | ||
420 | static unsigned int au_serial_in(struct uart_port *p, int offset) | 427 | static unsigned int au_serial_in(struct uart_port *p, int offset) |
421 | { | 428 | { |
422 | offset = map_8250_in_reg(p, offset) << p->regshift; | 429 | offset = map_8250_in_reg(p, offset) << p->regshift; |
@@ -428,7 +435,6 @@ static void au_serial_out(struct uart_port *p, int offset, int value) | |||
428 | offset = map_8250_out_reg(p, offset) << p->regshift; | 435 | offset = map_8250_out_reg(p, offset) << p->regshift; |
429 | __raw_writel(value, p->membase + offset); | 436 | __raw_writel(value, p->membase + offset); |
430 | } | 437 | } |
431 | #endif | ||
432 | 438 | ||
433 | static unsigned int tsi_serial_in(struct uart_port *p, int offset) | 439 | static unsigned int tsi_serial_in(struct uart_port *p, int offset) |
434 | { | 440 | { |
@@ -448,21 +454,40 @@ static void tsi_serial_out(struct uart_port *p, int offset, int value) | |||
448 | writeb(value, p->membase + offset); | 454 | writeb(value, p->membase + offset); |
449 | } | 455 | } |
450 | 456 | ||
457 | /* Save the LCR value so it can be re-written when a Busy Detect IRQ occurs. */ | ||
458 | static inline void dwapb_save_out_value(struct uart_port *p, int offset, | ||
459 | int value) | ||
460 | { | ||
461 | struct uart_8250_port *up = | ||
462 | container_of(p, struct uart_8250_port, port); | ||
463 | |||
464 | if (offset == UART_LCR) | ||
465 | up->lcr = value; | ||
466 | } | ||
467 | |||
468 | /* Read the IER to ensure any interrupt is cleared before returning from ISR. */ | ||
469 | static inline void dwapb_check_clear_ier(struct uart_port *p, int offset) | ||
470 | { | ||
471 | if (offset == UART_TX || offset == UART_IER) | ||
472 | p->serial_in(p, UART_IER); | ||
473 | } | ||
474 | |||
451 | static void dwapb_serial_out(struct uart_port *p, int offset, int value) | 475 | static void dwapb_serial_out(struct uart_port *p, int offset, int value) |
452 | { | 476 | { |
453 | int save_offset = offset; | 477 | int save_offset = offset; |
454 | offset = map_8250_out_reg(p, offset) << p->regshift; | 478 | offset = map_8250_out_reg(p, offset) << p->regshift; |
455 | /* Save the LCR value so it can be re-written when a | 479 | dwapb_save_out_value(p, save_offset, value); |
456 | * Busy Detect interrupt occurs. */ | ||
457 | if (save_offset == UART_LCR) { | ||
458 | struct uart_8250_port *up = (struct uart_8250_port *)p; | ||
459 | up->lcr = value; | ||
460 | } | ||
461 | writeb(value, p->membase + offset); | 480 | writeb(value, p->membase + offset); |
462 | /* Read the IER to ensure any interrupt is cleared before | 481 | dwapb_check_clear_ier(p, save_offset); |
463 | * returning from ISR. */ | 482 | } |
464 | if (save_offset == UART_TX || save_offset == UART_IER) | 483 | |
465 | value = p->serial_in(p, UART_IER); | 484 | static void dwapb32_serial_out(struct uart_port *p, int offset, int value) |
485 | { | ||
486 | int save_offset = offset; | ||
487 | offset = map_8250_out_reg(p, offset) << p->regshift; | ||
488 | dwapb_save_out_value(p, save_offset, value); | ||
489 | writel(value, p->membase + offset); | ||
490 | dwapb_check_clear_ier(p, save_offset); | ||
466 | } | 491 | } |
467 | 492 | ||
468 | static unsigned int io_serial_in(struct uart_port *p, int offset) | 493 | static unsigned int io_serial_in(struct uart_port *p, int offset) |
@@ -479,7 +504,8 @@ static void io_serial_out(struct uart_port *p, int offset, int value) | |||
479 | 504 | ||
480 | static void set_io_from_upio(struct uart_port *p) | 505 | static void set_io_from_upio(struct uart_port *p) |
481 | { | 506 | { |
482 | struct uart_8250_port *up = (struct uart_8250_port *)p; | 507 | struct uart_8250_port *up = |
508 | container_of(p, struct uart_8250_port, port); | ||
483 | switch (p->iotype) { | 509 | switch (p->iotype) { |
484 | case UPIO_HUB6: | 510 | case UPIO_HUB6: |
485 | p->serial_in = hub6_serial_in; | 511 | p->serial_in = hub6_serial_in; |
@@ -497,12 +523,11 @@ static void set_io_from_upio(struct uart_port *p) | |||
497 | p->serial_out = mem32_serial_out; | 523 | p->serial_out = mem32_serial_out; |
498 | break; | 524 | break; |
499 | 525 | ||
500 | #ifdef CONFIG_SERIAL_8250_AU1X00 | ||
501 | case UPIO_AU: | 526 | case UPIO_AU: |
502 | p->serial_in = au_serial_in; | 527 | p->serial_in = au_serial_in; |
503 | p->serial_out = au_serial_out; | 528 | p->serial_out = au_serial_out; |
504 | break; | 529 | break; |
505 | #endif | 530 | |
506 | case UPIO_TSI: | 531 | case UPIO_TSI: |
507 | p->serial_in = tsi_serial_in; | 532 | p->serial_in = tsi_serial_in; |
508 | p->serial_out = tsi_serial_out; | 533 | p->serial_out = tsi_serial_out; |
@@ -513,6 +538,11 @@ static void set_io_from_upio(struct uart_port *p) | |||
513 | p->serial_out = dwapb_serial_out; | 538 | p->serial_out = dwapb_serial_out; |
514 | break; | 539 | break; |
515 | 540 | ||
541 | case UPIO_DWAPB32: | ||
542 | p->serial_in = mem32_serial_in; | ||
543 | p->serial_out = dwapb32_serial_out; | ||
544 | break; | ||
545 | |||
516 | default: | 546 | default: |
517 | p->serial_in = io_serial_in; | 547 | p->serial_in = io_serial_in; |
518 | p->serial_out = io_serial_out; | 548 | p->serial_out = io_serial_out; |
@@ -529,10 +559,9 @@ serial_out_sync(struct uart_8250_port *up, int offset, int value) | |||
529 | switch (p->iotype) { | 559 | switch (p->iotype) { |
530 | case UPIO_MEM: | 560 | case UPIO_MEM: |
531 | case UPIO_MEM32: | 561 | case UPIO_MEM32: |
532 | #ifdef CONFIG_SERIAL_8250_AU1X00 | ||
533 | case UPIO_AU: | 562 | case UPIO_AU: |
534 | #endif | ||
535 | case UPIO_DWAPB: | 563 | case UPIO_DWAPB: |
564 | case UPIO_DWAPB32: | ||
536 | p->serial_out(p, offset, value); | 565 | p->serial_out(p, offset, value); |
537 | p->serial_in(p, UART_LCR); /* safe, no side-effects */ | 566 | p->serial_in(p, UART_LCR); /* safe, no side-effects */ |
538 | break; | 567 | break; |
@@ -567,7 +596,7 @@ static inline void _serial_dl_write(struct uart_8250_port *up, int value) | |||
567 | serial_outp(up, UART_DLM, value >> 8 & 0xff); | 596 | serial_outp(up, UART_DLM, value >> 8 & 0xff); |
568 | } | 597 | } |
569 | 598 | ||
570 | #if defined(CONFIG_SERIAL_8250_AU1X00) | 599 | #if defined(CONFIG_MIPS_ALCHEMY) |
571 | /* Au1x00 haven't got a standard divisor latch */ | 600 | /* Au1x00 haven't got a standard divisor latch */ |
572 | static int serial_dl_read(struct uart_8250_port *up) | 601 | static int serial_dl_read(struct uart_8250_port *up) |
573 | { | 602 | { |
@@ -650,13 +679,13 @@ static void serial8250_set_sleep(struct uart_8250_port *p, int sleep) | |||
650 | { | 679 | { |
651 | if (p->capabilities & UART_CAP_SLEEP) { | 680 | if (p->capabilities & UART_CAP_SLEEP) { |
652 | if (p->capabilities & UART_CAP_EFR) { | 681 | if (p->capabilities & UART_CAP_EFR) { |
653 | serial_outp(p, UART_LCR, 0xBF); | 682 | serial_outp(p, UART_LCR, UART_LCR_CONF_MODE_B); |
654 | serial_outp(p, UART_EFR, UART_EFR_ECB); | 683 | serial_outp(p, UART_EFR, UART_EFR_ECB); |
655 | serial_outp(p, UART_LCR, 0); | 684 | serial_outp(p, UART_LCR, 0); |
656 | } | 685 | } |
657 | serial_outp(p, UART_IER, sleep ? UART_IERX_SLEEP : 0); | 686 | serial_outp(p, UART_IER, sleep ? UART_IERX_SLEEP : 0); |
658 | if (p->capabilities & UART_CAP_EFR) { | 687 | if (p->capabilities & UART_CAP_EFR) { |
659 | serial_outp(p, UART_LCR, 0xBF); | 688 | serial_outp(p, UART_LCR, UART_LCR_CONF_MODE_B); |
660 | serial_outp(p, UART_EFR, 0); | 689 | serial_outp(p, UART_EFR, 0); |
661 | serial_outp(p, UART_LCR, 0); | 690 | serial_outp(p, UART_LCR, 0); |
662 | } | 691 | } |
@@ -749,7 +778,7 @@ static int size_fifo(struct uart_8250_port *up) | |||
749 | serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | | 778 | serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | |
750 | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); | 779 | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); |
751 | serial_outp(up, UART_MCR, UART_MCR_LOOP); | 780 | serial_outp(up, UART_MCR, UART_MCR_LOOP); |
752 | serial_outp(up, UART_LCR, UART_LCR_DLAB); | 781 | serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A); |
753 | old_dl = serial_dl_read(up); | 782 | old_dl = serial_dl_read(up); |
754 | serial_dl_write(up, 0x0001); | 783 | serial_dl_write(up, 0x0001); |
755 | serial_outp(up, UART_LCR, 0x03); | 784 | serial_outp(up, UART_LCR, 0x03); |
@@ -761,7 +790,7 @@ static int size_fifo(struct uart_8250_port *up) | |||
761 | serial_inp(up, UART_RX); | 790 | serial_inp(up, UART_RX); |
762 | serial_outp(up, UART_FCR, old_fcr); | 791 | serial_outp(up, UART_FCR, old_fcr); |
763 | serial_outp(up, UART_MCR, old_mcr); | 792 | serial_outp(up, UART_MCR, old_mcr); |
764 | serial_outp(up, UART_LCR, UART_LCR_DLAB); | 793 | serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A); |
765 | serial_dl_write(up, old_dl); | 794 | serial_dl_write(up, old_dl); |
766 | serial_outp(up, UART_LCR, old_lcr); | 795 | serial_outp(up, UART_LCR, old_lcr); |
767 | 796 | ||
@@ -779,7 +808,7 @@ static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p) | |||
779 | unsigned int id; | 808 | unsigned int id; |
780 | 809 | ||
781 | old_lcr = serial_inp(p, UART_LCR); | 810 | old_lcr = serial_inp(p, UART_LCR); |
782 | serial_outp(p, UART_LCR, UART_LCR_DLAB); | 811 | serial_outp(p, UART_LCR, UART_LCR_CONF_MODE_A); |
783 | 812 | ||
784 | old_dll = serial_inp(p, UART_DLL); | 813 | old_dll = serial_inp(p, UART_DLL); |
785 | old_dlm = serial_inp(p, UART_DLM); | 814 | old_dlm = serial_inp(p, UART_DLM); |
@@ -833,7 +862,7 @@ static void autoconfig_has_efr(struct uart_8250_port *up) | |||
833 | * recommended for new designs). | 862 | * recommended for new designs). |
834 | */ | 863 | */ |
835 | up->acr = 0; | 864 | up->acr = 0; |
836 | serial_out(up, UART_LCR, 0xBF); | 865 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); |
837 | serial_out(up, UART_EFR, UART_EFR_ECB); | 866 | serial_out(up, UART_EFR, UART_EFR_ECB); |
838 | serial_out(up, UART_LCR, 0x00); | 867 | serial_out(up, UART_LCR, 0x00); |
839 | id1 = serial_icr_read(up, UART_ID1); | 868 | id1 = serial_icr_read(up, UART_ID1); |
@@ -916,7 +945,7 @@ static int broken_efr(struct uart_8250_port *up) | |||
916 | /* | 945 | /* |
917 | * Exar ST16C2550 "A2" devices incorrectly detect as | 946 | * Exar ST16C2550 "A2" devices incorrectly detect as |
918 | * having an EFR, and report an ID of 0x0201. See | 947 | * having an EFR, and report an ID of 0x0201. See |
919 | * http://www.exar.com/info.php?pdf=dan180_oct2004.pdf | 948 | * http://linux.derkeiler.com/Mailing-Lists/Kernel/2004-11/4812.html |
920 | */ | 949 | */ |
921 | if (autoconfig_read_divisor_id(up) == 0x0201 && size_fifo(up) == 16) | 950 | if (autoconfig_read_divisor_id(up) == 0x0201 && size_fifo(up) == 16) |
922 | return 1; | 951 | return 1; |
@@ -942,7 +971,7 @@ static void autoconfig_16550a(struct uart_8250_port *up) | |||
942 | * Check for presence of the EFR when DLAB is set. | 971 | * Check for presence of the EFR when DLAB is set. |
943 | * Only ST16C650V1 UARTs pass this test. | 972 | * Only ST16C650V1 UARTs pass this test. |
944 | */ | 973 | */ |
945 | serial_outp(up, UART_LCR, UART_LCR_DLAB); | 974 | serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A); |
946 | if (serial_in(up, UART_EFR) == 0) { | 975 | if (serial_in(up, UART_EFR) == 0) { |
947 | serial_outp(up, UART_EFR, 0xA8); | 976 | serial_outp(up, UART_EFR, 0xA8); |
948 | if (serial_in(up, UART_EFR) != 0) { | 977 | if (serial_in(up, UART_EFR) != 0) { |
@@ -960,7 +989,7 @@ static void autoconfig_16550a(struct uart_8250_port *up) | |||
960 | * Maybe it requires 0xbf to be written to the LCR. | 989 | * Maybe it requires 0xbf to be written to the LCR. |
961 | * (other ST16C650V2 UARTs, TI16C752A, etc) | 990 | * (other ST16C650V2 UARTs, TI16C752A, etc) |
962 | */ | 991 | */ |
963 | serial_outp(up, UART_LCR, 0xBF); | 992 | serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B); |
964 | if (serial_in(up, UART_EFR) == 0 && !broken_efr(up)) { | 993 | if (serial_in(up, UART_EFR) == 0 && !broken_efr(up)) { |
965 | DEBUG_AUTOCONF("EFRv2 "); | 994 | DEBUG_AUTOCONF("EFRv2 "); |
966 | autoconfig_has_efr(up); | 995 | autoconfig_has_efr(up); |
@@ -1021,7 +1050,7 @@ static void autoconfig_16550a(struct uart_8250_port *up) | |||
1021 | serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); | 1050 | serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); |
1022 | status1 = serial_in(up, UART_IIR) >> 5; | 1051 | status1 = serial_in(up, UART_IIR) >> 5; |
1023 | serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO); | 1052 | serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO); |
1024 | serial_outp(up, UART_LCR, UART_LCR_DLAB); | 1053 | serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A); |
1025 | serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); | 1054 | serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); |
1026 | status2 = serial_in(up, UART_IIR) >> 5; | 1055 | status2 = serial_in(up, UART_IIR) >> 5; |
1027 | serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO); | 1056 | serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO); |
@@ -1069,6 +1098,15 @@ static void autoconfig_16550a(struct uart_8250_port *up) | |||
1069 | DEBUG_AUTOCONF("Couldn't force IER_UUE to 0 "); | 1098 | DEBUG_AUTOCONF("Couldn't force IER_UUE to 0 "); |
1070 | } | 1099 | } |
1071 | serial_outp(up, UART_IER, iersave); | 1100 | serial_outp(up, UART_IER, iersave); |
1101 | |||
1102 | /* | ||
1103 | * We distinguish between 16550A and U6 16550A by counting | ||
1104 | * how many bytes are in the FIFO. | ||
1105 | */ | ||
1106 | if (up->port.type == PORT_16550A && size_fifo(up) == 64) { | ||
1107 | up->port.type = PORT_U6_16550A; | ||
1108 | up->capabilities |= UART_CAP_AFE; | ||
1109 | } | ||
1072 | } | 1110 | } |
1073 | 1111 | ||
1074 | /* | 1112 | /* |
@@ -1087,7 +1125,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) | |||
1087 | if (!up->port.iobase && !up->port.mapbase && !up->port.membase) | 1125 | if (!up->port.iobase && !up->port.mapbase && !up->port.membase) |
1088 | return; | 1126 | return; |
1089 | 1127 | ||
1090 | DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04x, 0x%p): ", | 1128 | DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04lx, 0x%p): ", |
1091 | serial_index(&up->port), up->port.iobase, up->port.membase); | 1129 | serial_index(&up->port), up->port.iobase, up->port.membase); |
1092 | 1130 | ||
1093 | /* | 1131 | /* |
@@ -1171,7 +1209,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) | |||
1171 | * We also initialise the EFR (if any) to zero for later. The | 1209 | * We also initialise the EFR (if any) to zero for later. The |
1172 | * EFR occupies the same register location as the FCR and IIR. | 1210 | * EFR occupies the same register location as the FCR and IIR. |
1173 | */ | 1211 | */ |
1174 | serial_outp(up, UART_LCR, 0xBF); | 1212 | serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B); |
1175 | serial_outp(up, UART_EFR, 0); | 1213 | serial_outp(up, UART_EFR, 0); |
1176 | serial_outp(up, UART_LCR, 0); | 1214 | serial_outp(up, UART_LCR, 0); |
1177 | 1215 | ||
@@ -1212,12 +1250,6 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) | |||
1212 | } | 1250 | } |
1213 | #endif | 1251 | #endif |
1214 | 1252 | ||
1215 | #ifdef CONFIG_SERIAL_8250_AU1X00 | ||
1216 | /* if access method is AU, it is a 16550 with a quirk */ | ||
1217 | if (up->port.type == PORT_16550A && up->port.iotype == UPIO_AU) | ||
1218 | up->bugs |= UART_BUG_NOMSR; | ||
1219 | #endif | ||
1220 | |||
1221 | serial_outp(up, UART_LCR, save_lcr); | 1253 | serial_outp(up, UART_LCR, save_lcr); |
1222 | 1254 | ||
1223 | if (up->capabilities != uart_config[up->port.type].flags) { | 1255 | if (up->capabilities != uart_config[up->port.type].flags) { |
@@ -1313,7 +1345,8 @@ static inline void __stop_tx(struct uart_8250_port *p) | |||
1313 | 1345 | ||
1314 | static void serial8250_stop_tx(struct uart_port *port) | 1346 | static void serial8250_stop_tx(struct uart_port *port) |
1315 | { | 1347 | { |
1316 | struct uart_8250_port *up = (struct uart_8250_port *)port; | 1348 | struct uart_8250_port *up = |
1349 | container_of(port, struct uart_8250_port, port); | ||
1317 | 1350 | ||
1318 | __stop_tx(up); | 1351 | __stop_tx(up); |
1319 | 1352 | ||
@@ -1330,21 +1363,20 @@ static void transmit_chars(struct uart_8250_port *up); | |||
1330 | 1363 | ||
1331 | static void serial8250_start_tx(struct uart_port *port) | 1364 | static void serial8250_start_tx(struct uart_port *port) |
1332 | { | 1365 | { |
1333 | struct uart_8250_port *up = (struct uart_8250_port *)port; | 1366 | struct uart_8250_port *up = |
1367 | container_of(port, struct uart_8250_port, port); | ||
1334 | 1368 | ||
1335 | if (!(up->ier & UART_IER_THRI)) { | 1369 | if (!(up->ier & UART_IER_THRI)) { |
1336 | up->ier |= UART_IER_THRI; | 1370 | up->ier |= UART_IER_THRI; |
1337 | serial_out(up, UART_IER, up->ier); | 1371 | serial_out(up, UART_IER, up->ier); |
1338 | 1372 | ||
1339 | if (up->bugs & UART_BUG_TXEN) { | 1373 | if (up->bugs & UART_BUG_TXEN) { |
1340 | unsigned char lsr, iir; | 1374 | unsigned char lsr; |
1341 | lsr = serial_in(up, UART_LSR); | 1375 | lsr = serial_in(up, UART_LSR); |
1342 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; | 1376 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; |
1343 | iir = serial_in(up, UART_IIR) & 0x0f; | ||
1344 | if ((up->port.type == PORT_RM9000) ? | 1377 | if ((up->port.type == PORT_RM9000) ? |
1345 | (lsr & UART_LSR_THRE && | 1378 | (lsr & UART_LSR_THRE) : |
1346 | (iir == UART_IIR_NO_INT || iir == UART_IIR_THRI)) : | 1379 | (lsr & UART_LSR_TEMT)) |
1347 | (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT)) | ||
1348 | transmit_chars(up); | 1380 | transmit_chars(up); |
1349 | } | 1381 | } |
1350 | } | 1382 | } |
@@ -1360,7 +1392,8 @@ static void serial8250_start_tx(struct uart_port *port) | |||
1360 | 1392 | ||
1361 | static void serial8250_stop_rx(struct uart_port *port) | 1393 | static void serial8250_stop_rx(struct uart_port *port) |
1362 | { | 1394 | { |
1363 | struct uart_8250_port *up = (struct uart_8250_port *)port; | 1395 | struct uart_8250_port *up = |
1396 | container_of(port, struct uart_8250_port, port); | ||
1364 | 1397 | ||
1365 | up->ier &= ~UART_IER_RLSI; | 1398 | up->ier &= ~UART_IER_RLSI; |
1366 | up->port.read_status_mask &= ~UART_LSR_DR; | 1399 | up->port.read_status_mask &= ~UART_LSR_DR; |
@@ -1369,7 +1402,8 @@ static void serial8250_stop_rx(struct uart_port *port) | |||
1369 | 1402 | ||
1370 | static void serial8250_enable_ms(struct uart_port *port) | 1403 | static void serial8250_enable_ms(struct uart_port *port) |
1371 | { | 1404 | { |
1372 | struct uart_8250_port *up = (struct uart_8250_port *)port; | 1405 | struct uart_8250_port *up = |
1406 | container_of(port, struct uart_8250_port, port); | ||
1373 | 1407 | ||
1374 | /* no MSR capabilities */ | 1408 | /* no MSR capabilities */ |
1375 | if (up->bugs & UART_BUG_NOMSR) | 1409 | if (up->bugs & UART_BUG_NOMSR) |
@@ -1382,7 +1416,7 @@ static void serial8250_enable_ms(struct uart_port *port) | |||
1382 | static void | 1416 | static void |
1383 | receive_chars(struct uart_8250_port *up, unsigned int *status) | 1417 | receive_chars(struct uart_8250_port *up, unsigned int *status) |
1384 | { | 1418 | { |
1385 | struct tty_struct *tty = up->port.info->port.tty; | 1419 | struct tty_struct *tty = up->port.state->port.tty; |
1386 | unsigned char ch, lsr = *status; | 1420 | unsigned char ch, lsr = *status; |
1387 | int max_count = 256; | 1421 | int max_count = 256; |
1388 | char flag; | 1422 | char flag; |
@@ -1457,7 +1491,7 @@ ignore_char: | |||
1457 | 1491 | ||
1458 | static void transmit_chars(struct uart_8250_port *up) | 1492 | static void transmit_chars(struct uart_8250_port *up) |
1459 | { | 1493 | { |
1460 | struct circ_buf *xmit = &up->port.info->xmit; | 1494 | struct circ_buf *xmit = &up->port.state->xmit; |
1461 | int count; | 1495 | int count; |
1462 | 1496 | ||
1463 | if (up->port.x_char) { | 1497 | if (up->port.x_char) { |
@@ -1500,7 +1534,7 @@ static unsigned int check_modem_status(struct uart_8250_port *up) | |||
1500 | status |= up->msr_saved_flags; | 1534 | status |= up->msr_saved_flags; |
1501 | up->msr_saved_flags = 0; | 1535 | up->msr_saved_flags = 0; |
1502 | if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI && | 1536 | if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI && |
1503 | up->port.info != NULL) { | 1537 | up->port.state != NULL) { |
1504 | if (status & UART_MSR_TERI) | 1538 | if (status & UART_MSR_TERI) |
1505 | up->port.icount.rng++; | 1539 | up->port.icount.rng++; |
1506 | if (status & UART_MSR_DDSR) | 1540 | if (status & UART_MSR_DDSR) |
@@ -1510,7 +1544,7 @@ static unsigned int check_modem_status(struct uart_8250_port *up) | |||
1510 | if (status & UART_MSR_DCTS) | 1544 | if (status & UART_MSR_DCTS) |
1511 | uart_handle_cts_change(&up->port, status & UART_MSR_CTS); | 1545 | uart_handle_cts_change(&up->port, status & UART_MSR_CTS); |
1512 | 1546 | ||
1513 | wake_up_interruptible(&up->port.info->delta_msr_wait); | 1547 | wake_up_interruptible(&up->port.state->port.delta_msr_wait); |
1514 | } | 1548 | } |
1515 | 1549 | ||
1516 | return status; | 1550 | return status; |
@@ -1577,7 +1611,8 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id) | |||
1577 | handled = 1; | 1611 | handled = 1; |
1578 | 1612 | ||
1579 | end = NULL; | 1613 | end = NULL; |
1580 | } else if (up->port.iotype == UPIO_DWAPB && | 1614 | } else if ((up->port.iotype == UPIO_DWAPB || |
1615 | up->port.iotype == UPIO_DWAPB32) && | ||
1581 | (iir & UART_IIR_BUSY) == UART_IIR_BUSY) { | 1616 | (iir & UART_IIR_BUSY) == UART_IIR_BUSY) { |
1582 | /* The DesignWare APB UART has an Busy Detect (0x07) | 1617 | /* The DesignWare APB UART has an Busy Detect (0x07) |
1583 | * interrupt meaning an LCR write attempt occured while the | 1618 | * interrupt meaning an LCR write attempt occured while the |
@@ -1597,8 +1632,8 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id) | |||
1597 | 1632 | ||
1598 | if (l == i->head && pass_counter++ > PASS_LIMIT) { | 1633 | if (l == i->head && pass_counter++ > PASS_LIMIT) { |
1599 | /* If we hit this, we're dead. */ | 1634 | /* If we hit this, we're dead. */ |
1600 | printk(KERN_ERR "serial8250: too much work for " | 1635 | printk_ratelimited(KERN_ERR |
1601 | "irq%d\n", irq); | 1636 | "serial8250: too much work for irq%d\n", irq); |
1602 | break; | 1637 | break; |
1603 | } | 1638 | } |
1604 | } while (l != end); | 1639 | } while (l != end); |
@@ -1677,7 +1712,7 @@ static int serial_link_irq_chain(struct uart_8250_port *up) | |||
1677 | INIT_LIST_HEAD(&up->list); | 1712 | INIT_LIST_HEAD(&up->list); |
1678 | i->head = &up->list; | 1713 | i->head = &up->list; |
1679 | spin_unlock_irq(&i->lock); | 1714 | spin_unlock_irq(&i->lock); |
1680 | 1715 | irq_flags |= up->port.irqflags; | |
1681 | ret = request_irq(up->port.irq, serial8250_interrupt, | 1716 | ret = request_irq(up->port.irq, serial8250_interrupt, |
1682 | irq_flags, "serial", i); | 1717 | irq_flags, "serial", i); |
1683 | if (ret < 0) | 1718 | if (ret < 0) |
@@ -1713,12 +1748,6 @@ static void serial_unlink_irq_chain(struct uart_8250_port *up) | |||
1713 | mutex_unlock(&hash_mutex); | 1748 | mutex_unlock(&hash_mutex); |
1714 | } | 1749 | } |
1715 | 1750 | ||
1716 | /* Base timer interval for polling */ | ||
1717 | static inline int poll_timeout(int timeout) | ||
1718 | { | ||
1719 | return timeout > 6 ? (timeout / 2 - 2) : 1; | ||
1720 | } | ||
1721 | |||
1722 | /* | 1751 | /* |
1723 | * This function is used to handle ports that do not have an | 1752 | * This function is used to handle ports that do not have an |
1724 | * interrupt. This doesn't work very well for 16450's, but gives | 1753 | * interrupt. This doesn't work very well for 16450's, but gives |
@@ -1733,7 +1762,7 @@ static void serial8250_timeout(unsigned long data) | |||
1733 | iir = serial_in(up, UART_IIR); | 1762 | iir = serial_in(up, UART_IIR); |
1734 | if (!(iir & UART_IIR_NO_INT)) | 1763 | if (!(iir & UART_IIR_NO_INT)) |
1735 | serial8250_handle_port(up); | 1764 | serial8250_handle_port(up); |
1736 | mod_timer(&up->timer, jiffies + poll_timeout(up->port.timeout)); | 1765 | mod_timer(&up->timer, jiffies + uart_poll_timeout(&up->port)); |
1737 | } | 1766 | } |
1738 | 1767 | ||
1739 | static void serial8250_backup_timeout(unsigned long data) | 1768 | static void serial8250_backup_timeout(unsigned long data) |
@@ -1764,7 +1793,7 @@ static void serial8250_backup_timeout(unsigned long data) | |||
1764 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; | 1793 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; |
1765 | spin_unlock_irqrestore(&up->port.lock, flags); | 1794 | spin_unlock_irqrestore(&up->port.lock, flags); |
1766 | if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) && | 1795 | if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) && |
1767 | (!uart_circ_empty(&up->port.info->xmit) || up->port.x_char) && | 1796 | (!uart_circ_empty(&up->port.state->xmit) || up->port.x_char) && |
1768 | (lsr & UART_LSR_THRE)) { | 1797 | (lsr & UART_LSR_THRE)) { |
1769 | iir &= ~(UART_IIR_ID | UART_IIR_NO_INT); | 1798 | iir &= ~(UART_IIR_ID | UART_IIR_NO_INT); |
1770 | iir |= UART_IIR_THRI; | 1799 | iir |= UART_IIR_THRI; |
@@ -1778,12 +1807,13 @@ static void serial8250_backup_timeout(unsigned long data) | |||
1778 | 1807 | ||
1779 | /* Standard timer interval plus 0.2s to keep the port running */ | 1808 | /* Standard timer interval plus 0.2s to keep the port running */ |
1780 | mod_timer(&up->timer, | 1809 | mod_timer(&up->timer, |
1781 | jiffies + poll_timeout(up->port.timeout) + HZ / 5); | 1810 | jiffies + uart_poll_timeout(&up->port) + HZ / 5); |
1782 | } | 1811 | } |
1783 | 1812 | ||
1784 | static unsigned int serial8250_tx_empty(struct uart_port *port) | 1813 | static unsigned int serial8250_tx_empty(struct uart_port *port) |
1785 | { | 1814 | { |
1786 | struct uart_8250_port *up = (struct uart_8250_port *)port; | 1815 | struct uart_8250_port *up = |
1816 | container_of(port, struct uart_8250_port, port); | ||
1787 | unsigned long flags; | 1817 | unsigned long flags; |
1788 | unsigned int lsr; | 1818 | unsigned int lsr; |
1789 | 1819 | ||
@@ -1792,12 +1822,13 @@ static unsigned int serial8250_tx_empty(struct uart_port *port) | |||
1792 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; | 1822 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; |
1793 | spin_unlock_irqrestore(&up->port.lock, flags); | 1823 | spin_unlock_irqrestore(&up->port.lock, flags); |
1794 | 1824 | ||
1795 | return lsr & UART_LSR_TEMT ? TIOCSER_TEMT : 0; | 1825 | return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0; |
1796 | } | 1826 | } |
1797 | 1827 | ||
1798 | static unsigned int serial8250_get_mctrl(struct uart_port *port) | 1828 | static unsigned int serial8250_get_mctrl(struct uart_port *port) |
1799 | { | 1829 | { |
1800 | struct uart_8250_port *up = (struct uart_8250_port *)port; | 1830 | struct uart_8250_port *up = |
1831 | container_of(port, struct uart_8250_port, port); | ||
1801 | unsigned int status; | 1832 | unsigned int status; |
1802 | unsigned int ret; | 1833 | unsigned int ret; |
1803 | 1834 | ||
@@ -1817,7 +1848,8 @@ static unsigned int serial8250_get_mctrl(struct uart_port *port) | |||
1817 | 1848 | ||
1818 | static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl) | 1849 | static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl) |
1819 | { | 1850 | { |
1820 | struct uart_8250_port *up = (struct uart_8250_port *)port; | 1851 | struct uart_8250_port *up = |
1852 | container_of(port, struct uart_8250_port, port); | ||
1821 | unsigned char mcr = 0; | 1853 | unsigned char mcr = 0; |
1822 | 1854 | ||
1823 | if (mctrl & TIOCM_RTS) | 1855 | if (mctrl & TIOCM_RTS) |
@@ -1838,7 +1870,8 @@ static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
1838 | 1870 | ||
1839 | static void serial8250_break_ctl(struct uart_port *port, int break_state) | 1871 | static void serial8250_break_ctl(struct uart_port *port, int break_state) |
1840 | { | 1872 | { |
1841 | struct uart_8250_port *up = (struct uart_8250_port *)port; | 1873 | struct uart_8250_port *up = |
1874 | container_of(port, struct uart_8250_port, port); | ||
1842 | unsigned long flags; | 1875 | unsigned long flags; |
1843 | 1876 | ||
1844 | spin_lock_irqsave(&up->port.lock, flags); | 1877 | spin_lock_irqsave(&up->port.lock, flags); |
@@ -1850,8 +1883,6 @@ static void serial8250_break_ctl(struct uart_port *port, int break_state) | |||
1850 | spin_unlock_irqrestore(&up->port.lock, flags); | 1883 | spin_unlock_irqrestore(&up->port.lock, flags); |
1851 | } | 1884 | } |
1852 | 1885 | ||
1853 | #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) | ||
1854 | |||
1855 | /* | 1886 | /* |
1856 | * Wait for transmitter & holding register to empty | 1887 | * Wait for transmitter & holding register to empty |
1857 | */ | 1888 | */ |
@@ -1860,15 +1891,17 @@ static void wait_for_xmitr(struct uart_8250_port *up, int bits) | |||
1860 | unsigned int status, tmout = 10000; | 1891 | unsigned int status, tmout = 10000; |
1861 | 1892 | ||
1862 | /* Wait up to 10ms for the character(s) to be sent. */ | 1893 | /* Wait up to 10ms for the character(s) to be sent. */ |
1863 | do { | 1894 | for (;;) { |
1864 | status = serial_in(up, UART_LSR); | 1895 | status = serial_in(up, UART_LSR); |
1865 | 1896 | ||
1866 | up->lsr_saved_flags |= status & LSR_SAVE_FLAGS; | 1897 | up->lsr_saved_flags |= status & LSR_SAVE_FLAGS; |
1867 | 1898 | ||
1899 | if ((status & bits) == bits) | ||
1900 | break; | ||
1868 | if (--tmout == 0) | 1901 | if (--tmout == 0) |
1869 | break; | 1902 | break; |
1870 | udelay(1); | 1903 | udelay(1); |
1871 | } while ((status & bits) != bits); | 1904 | } |
1872 | 1905 | ||
1873 | /* Wait up to 1s for flow control if necessary */ | 1906 | /* Wait up to 1s for flow control if necessary */ |
1874 | if (up->port.flags & UPF_CONS_FLOW) { | 1907 | if (up->port.flags & UPF_CONS_FLOW) { |
@@ -1892,11 +1925,12 @@ static void wait_for_xmitr(struct uart_8250_port *up, int bits) | |||
1892 | 1925 | ||
1893 | static int serial8250_get_poll_char(struct uart_port *port) | 1926 | static int serial8250_get_poll_char(struct uart_port *port) |
1894 | { | 1927 | { |
1895 | struct uart_8250_port *up = (struct uart_8250_port *)port; | 1928 | struct uart_8250_port *up = |
1929 | container_of(port, struct uart_8250_port, port); | ||
1896 | unsigned char lsr = serial_inp(up, UART_LSR); | 1930 | unsigned char lsr = serial_inp(up, UART_LSR); |
1897 | 1931 | ||
1898 | while (!(lsr & UART_LSR_DR)) | 1932 | if (!(lsr & UART_LSR_DR)) |
1899 | lsr = serial_inp(up, UART_LSR); | 1933 | return NO_POLL_CHAR; |
1900 | 1934 | ||
1901 | return serial_inp(up, UART_RX); | 1935 | return serial_inp(up, UART_RX); |
1902 | } | 1936 | } |
@@ -1906,7 +1940,8 @@ static void serial8250_put_poll_char(struct uart_port *port, | |||
1906 | unsigned char c) | 1940 | unsigned char c) |
1907 | { | 1941 | { |
1908 | unsigned int ier; | 1942 | unsigned int ier; |
1909 | struct uart_8250_port *up = (struct uart_8250_port *)port; | 1943 | struct uart_8250_port *up = |
1944 | container_of(port, struct uart_8250_port, port); | ||
1910 | 1945 | ||
1911 | /* | 1946 | /* |
1912 | * First save the IER then disable the interrupts | 1947 | * First save the IER then disable the interrupts |
@@ -1940,11 +1975,14 @@ static void serial8250_put_poll_char(struct uart_port *port, | |||
1940 | 1975 | ||
1941 | static int serial8250_startup(struct uart_port *port) | 1976 | static int serial8250_startup(struct uart_port *port) |
1942 | { | 1977 | { |
1943 | struct uart_8250_port *up = (struct uart_8250_port *)port; | 1978 | struct uart_8250_port *up = |
1979 | container_of(port, struct uart_8250_port, port); | ||
1944 | unsigned long flags; | 1980 | unsigned long flags; |
1945 | unsigned char lsr, iir; | 1981 | unsigned char lsr, iir; |
1946 | int retval; | 1982 | int retval; |
1947 | 1983 | ||
1984 | up->port.fifosize = uart_config[up->port.type].fifo_size; | ||
1985 | up->tx_loadsz = uart_config[up->port.type].tx_loadsz; | ||
1948 | up->capabilities = uart_config[up->port.type].flags; | 1986 | up->capabilities = uart_config[up->port.type].flags; |
1949 | up->mcr = 0; | 1987 | up->mcr = 0; |
1950 | 1988 | ||
@@ -1954,7 +1992,7 @@ static int serial8250_startup(struct uart_port *port) | |||
1954 | if (up->port.type == PORT_16C950) { | 1992 | if (up->port.type == PORT_16C950) { |
1955 | /* Wake up and initialize UART */ | 1993 | /* Wake up and initialize UART */ |
1956 | up->acr = 0; | 1994 | up->acr = 0; |
1957 | serial_outp(up, UART_LCR, 0xBF); | 1995 | serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B); |
1958 | serial_outp(up, UART_EFR, UART_EFR_ECB); | 1996 | serial_outp(up, UART_EFR, UART_EFR_ECB); |
1959 | serial_outp(up, UART_IER, 0); | 1997 | serial_outp(up, UART_IER, 0); |
1960 | serial_outp(up, UART_LCR, 0); | 1998 | serial_outp(up, UART_LCR, 0); |
@@ -2004,7 +2042,7 @@ static int serial8250_startup(struct uart_port *port) | |||
2004 | if (up->port.type == PORT_16850) { | 2042 | if (up->port.type == PORT_16850) { |
2005 | unsigned char fctr; | 2043 | unsigned char fctr; |
2006 | 2044 | ||
2007 | serial_outp(up, UART_LCR, 0xbf); | 2045 | serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B); |
2008 | 2046 | ||
2009 | fctr = serial_inp(up, UART_FCTR) & ~(UART_FCTR_RX|UART_FCTR_TX); | 2047 | fctr = serial_inp(up, UART_FCTR) & ~(UART_FCTR_RX|UART_FCTR_TX); |
2010 | serial_outp(up, UART_FCTR, fctr | UART_FCTR_TRGD | UART_FCTR_RX); | 2048 | serial_outp(up, UART_FCTR, fctr | UART_FCTR_TRGD | UART_FCTR_RX); |
@@ -2026,7 +2064,7 @@ static int serial8250_startup(struct uart_port *port) | |||
2026 | * allow register changes to become visible. | 2064 | * allow register changes to become visible. |
2027 | */ | 2065 | */ |
2028 | spin_lock_irqsave(&up->port.lock, flags); | 2066 | spin_lock_irqsave(&up->port.lock, flags); |
2029 | if (up->port.flags & UPF_SHARE_IRQ) | 2067 | if (up->port.irqflags & IRQF_SHARED) |
2030 | disable_irq_nosync(up->port.irq); | 2068 | disable_irq_nosync(up->port.irq); |
2031 | 2069 | ||
2032 | wait_for_xmitr(up, UART_LSR_THRE); | 2070 | wait_for_xmitr(up, UART_LSR_THRE); |
@@ -2039,7 +2077,7 @@ static int serial8250_startup(struct uart_port *port) | |||
2039 | iir = serial_in(up, UART_IIR); | 2077 | iir = serial_in(up, UART_IIR); |
2040 | serial_out(up, UART_IER, 0); | 2078 | serial_out(up, UART_IER, 0); |
2041 | 2079 | ||
2042 | if (up->port.flags & UPF_SHARE_IRQ) | 2080 | if (up->port.irqflags & IRQF_SHARED) |
2043 | enable_irq(up->port.irq); | 2081 | enable_irq(up->port.irq); |
2044 | spin_unlock_irqrestore(&up->port.lock, flags); | 2082 | spin_unlock_irqrestore(&up->port.lock, flags); |
2045 | 2083 | ||
@@ -2062,7 +2100,7 @@ static int serial8250_startup(struct uart_port *port) | |||
2062 | up->timer.function = serial8250_backup_timeout; | 2100 | up->timer.function = serial8250_backup_timeout; |
2063 | up->timer.data = (unsigned long)up; | 2101 | up->timer.data = (unsigned long)up; |
2064 | mod_timer(&up->timer, jiffies + | 2102 | mod_timer(&up->timer, jiffies + |
2065 | poll_timeout(up->port.timeout) + HZ / 5); | 2103 | uart_poll_timeout(port) + HZ / 5); |
2066 | } | 2104 | } |
2067 | 2105 | ||
2068 | /* | 2106 | /* |
@@ -2072,7 +2110,7 @@ static int serial8250_startup(struct uart_port *port) | |||
2072 | */ | 2110 | */ |
2073 | if (!is_real_interrupt(up->port.irq)) { | 2111 | if (!is_real_interrupt(up->port.irq)) { |
2074 | up->timer.data = (unsigned long)up; | 2112 | up->timer.data = (unsigned long)up; |
2075 | mod_timer(&up->timer, jiffies + poll_timeout(up->port.timeout)); | 2113 | mod_timer(&up->timer, jiffies + uart_poll_timeout(port)); |
2076 | } else { | 2114 | } else { |
2077 | retval = serial_link_irq_chain(up); | 2115 | retval = serial_link_irq_chain(up); |
2078 | if (retval) | 2116 | if (retval) |
@@ -2108,7 +2146,7 @@ static int serial8250_startup(struct uart_port *port) | |||
2108 | is variable. So, let's just don't test if we receive | 2146 | is variable. So, let's just don't test if we receive |
2109 | TX irq. This way, we'll never enable UART_BUG_TXEN. | 2147 | TX irq. This way, we'll never enable UART_BUG_TXEN. |
2110 | */ | 2148 | */ |
2111 | if (up->port.flags & UPF_NO_TXEN_TEST) | 2149 | if (skip_txen_test || up->port.flags & UPF_NO_TXEN_TEST) |
2112 | goto dont_test_tx_en; | 2150 | goto dont_test_tx_en; |
2113 | 2151 | ||
2114 | /* | 2152 | /* |
@@ -2168,7 +2206,8 @@ dont_test_tx_en: | |||
2168 | 2206 | ||
2169 | static void serial8250_shutdown(struct uart_port *port) | 2207 | static void serial8250_shutdown(struct uart_port *port) |
2170 | { | 2208 | { |
2171 | struct uart_8250_port *up = (struct uart_8250_port *)port; | 2209 | struct uart_8250_port *up = |
2210 | container_of(port, struct uart_8250_port, port); | ||
2172 | unsigned long flags; | 2211 | unsigned long flags; |
2173 | 2212 | ||
2174 | /* | 2213 | /* |
@@ -2233,11 +2272,12 @@ static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int | |||
2233 | return quot; | 2272 | return quot; |
2234 | } | 2273 | } |
2235 | 2274 | ||
2236 | static void | 2275 | void |
2237 | serial8250_set_termios(struct uart_port *port, struct ktermios *termios, | 2276 | serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, |
2238 | struct ktermios *old) | 2277 | struct ktermios *old) |
2239 | { | 2278 | { |
2240 | struct uart_8250_port *up = (struct uart_8250_port *)port; | 2279 | struct uart_8250_port *up = |
2280 | container_of(port, struct uart_8250_port, port); | ||
2241 | unsigned char cval, fcr = 0; | 2281 | unsigned char cval, fcr = 0; |
2242 | unsigned long flags; | 2282 | unsigned long flags; |
2243 | unsigned int baud, quot; | 2283 | unsigned int baud, quot; |
@@ -2272,7 +2312,9 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios, | |||
2272 | /* | 2312 | /* |
2273 | * Ask the core to calculate the divisor for us. | 2313 | * Ask the core to calculate the divisor for us. |
2274 | */ | 2314 | */ |
2275 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); | 2315 | baud = uart_get_baud_rate(port, termios, old, |
2316 | port->uartclk / 16 / 0xffff, | ||
2317 | port->uartclk / 16); | ||
2276 | quot = serial8250_get_divisor(port, baud); | 2318 | quot = serial8250_get_divisor(port, baud); |
2277 | 2319 | ||
2278 | /* | 2320 | /* |
@@ -2363,7 +2405,7 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios, | |||
2363 | if (termios->c_cflag & CRTSCTS) | 2405 | if (termios->c_cflag & CRTSCTS) |
2364 | efr |= UART_EFR_CTS; | 2406 | efr |= UART_EFR_CTS; |
2365 | 2407 | ||
2366 | serial_outp(up, UART_LCR, 0xBF); | 2408 | serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B); |
2367 | serial_outp(up, UART_EFR, efr); | 2409 | serial_outp(up, UART_EFR, efr); |
2368 | } | 2410 | } |
2369 | 2411 | ||
@@ -2409,23 +2451,53 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios, | |||
2409 | if (tty_termios_baud_rate(termios)) | 2451 | if (tty_termios_baud_rate(termios)) |
2410 | tty_termios_encode_baud_rate(termios, baud, baud); | 2452 | tty_termios_encode_baud_rate(termios, baud, baud); |
2411 | } | 2453 | } |
2454 | EXPORT_SYMBOL(serial8250_do_set_termios); | ||
2412 | 2455 | ||
2413 | static void | 2456 | static void |
2414 | serial8250_pm(struct uart_port *port, unsigned int state, | 2457 | serial8250_set_termios(struct uart_port *port, struct ktermios *termios, |
2415 | unsigned int oldstate) | 2458 | struct ktermios *old) |
2416 | { | 2459 | { |
2417 | struct uart_8250_port *p = (struct uart_8250_port *)port; | 2460 | if (port->set_termios) |
2461 | port->set_termios(port, termios, old); | ||
2462 | else | ||
2463 | serial8250_do_set_termios(port, termios, old); | ||
2464 | } | ||
2465 | |||
2466 | static void | ||
2467 | serial8250_set_ldisc(struct uart_port *port, int new) | ||
2468 | { | ||
2469 | if (new == N_PPS) { | ||
2470 | port->flags |= UPF_HARDPPS_CD; | ||
2471 | serial8250_enable_ms(port); | ||
2472 | } else | ||
2473 | port->flags &= ~UPF_HARDPPS_CD; | ||
2474 | } | ||
2475 | |||
2476 | |||
2477 | void serial8250_do_pm(struct uart_port *port, unsigned int state, | ||
2478 | unsigned int oldstate) | ||
2479 | { | ||
2480 | struct uart_8250_port *p = | ||
2481 | container_of(port, struct uart_8250_port, port); | ||
2418 | 2482 | ||
2419 | serial8250_set_sleep(p, state != 0); | 2483 | serial8250_set_sleep(p, state != 0); |
2484 | } | ||
2485 | EXPORT_SYMBOL(serial8250_do_pm); | ||
2420 | 2486 | ||
2421 | if (p->pm) | 2487 | static void |
2422 | p->pm(port, state, oldstate); | 2488 | serial8250_pm(struct uart_port *port, unsigned int state, |
2489 | unsigned int oldstate) | ||
2490 | { | ||
2491 | if (port->pm) | ||
2492 | port->pm(port, state, oldstate); | ||
2493 | else | ||
2494 | serial8250_do_pm(port, state, oldstate); | ||
2423 | } | 2495 | } |
2424 | 2496 | ||
2425 | static unsigned int serial8250_port_size(struct uart_8250_port *pt) | 2497 | static unsigned int serial8250_port_size(struct uart_8250_port *pt) |
2426 | { | 2498 | { |
2427 | if (pt->port.iotype == UPIO_AU) | 2499 | if (pt->port.iotype == UPIO_AU) |
2428 | return 0x100000; | 2500 | return 0x1000; |
2429 | #ifdef CONFIG_ARCH_OMAP | 2501 | #ifdef CONFIG_ARCH_OMAP |
2430 | if (is_omap_port(pt)) | 2502 | if (is_omap_port(pt)) |
2431 | return 0x16 << pt->port.regshift; | 2503 | return 0x16 << pt->port.regshift; |
@@ -2447,6 +2519,7 @@ static int serial8250_request_std_resource(struct uart_8250_port *up) | |||
2447 | case UPIO_MEM32: | 2519 | case UPIO_MEM32: |
2448 | case UPIO_MEM: | 2520 | case UPIO_MEM: |
2449 | case UPIO_DWAPB: | 2521 | case UPIO_DWAPB: |
2522 | case UPIO_DWAPB32: | ||
2450 | if (!up->port.mapbase) | 2523 | if (!up->port.mapbase) |
2451 | break; | 2524 | break; |
2452 | 2525 | ||
@@ -2484,6 +2557,7 @@ static void serial8250_release_std_resource(struct uart_8250_port *up) | |||
2484 | case UPIO_MEM32: | 2557 | case UPIO_MEM32: |
2485 | case UPIO_MEM: | 2558 | case UPIO_MEM: |
2486 | case UPIO_DWAPB: | 2559 | case UPIO_DWAPB: |
2560 | case UPIO_DWAPB32: | ||
2487 | if (!up->port.mapbase) | 2561 | if (!up->port.mapbase) |
2488 | break; | 2562 | break; |
2489 | 2563 | ||
@@ -2537,7 +2611,8 @@ static void serial8250_release_rsa_resource(struct uart_8250_port *up) | |||
2537 | 2611 | ||
2538 | static void serial8250_release_port(struct uart_port *port) | 2612 | static void serial8250_release_port(struct uart_port *port) |
2539 | { | 2613 | { |
2540 | struct uart_8250_port *up = (struct uart_8250_port *)port; | 2614 | struct uart_8250_port *up = |
2615 | container_of(port, struct uart_8250_port, port); | ||
2541 | 2616 | ||
2542 | serial8250_release_std_resource(up); | 2617 | serial8250_release_std_resource(up); |
2543 | if (up->port.type == PORT_RSA) | 2618 | if (up->port.type == PORT_RSA) |
@@ -2546,7 +2621,8 @@ static void serial8250_release_port(struct uart_port *port) | |||
2546 | 2621 | ||
2547 | static int serial8250_request_port(struct uart_port *port) | 2622 | static int serial8250_request_port(struct uart_port *port) |
2548 | { | 2623 | { |
2549 | struct uart_8250_port *up = (struct uart_8250_port *)port; | 2624 | struct uart_8250_port *up = |
2625 | container_of(port, struct uart_8250_port, port); | ||
2550 | int ret = 0; | 2626 | int ret = 0; |
2551 | 2627 | ||
2552 | ret = serial8250_request_std_resource(up); | 2628 | ret = serial8250_request_std_resource(up); |
@@ -2561,7 +2637,8 @@ static int serial8250_request_port(struct uart_port *port) | |||
2561 | 2637 | ||
2562 | static void serial8250_config_port(struct uart_port *port, int flags) | 2638 | static void serial8250_config_port(struct uart_port *port, int flags) |
2563 | { | 2639 | { |
2564 | struct uart_8250_port *up = (struct uart_8250_port *)port; | 2640 | struct uart_8250_port *up = |
2641 | container_of(port, struct uart_8250_port, port); | ||
2565 | int probeflags = PROBE_ANY; | 2642 | int probeflags = PROBE_ANY; |
2566 | int ret; | 2643 | int ret; |
2567 | 2644 | ||
@@ -2582,6 +2659,11 @@ static void serial8250_config_port(struct uart_port *port, int flags) | |||
2582 | 2659 | ||
2583 | if (flags & UART_CONFIG_TYPE) | 2660 | if (flags & UART_CONFIG_TYPE) |
2584 | autoconfig(up, probeflags); | 2661 | autoconfig(up, probeflags); |
2662 | |||
2663 | /* if access method is AU, it is a 16550 with a quirk */ | ||
2664 | if (up->port.type == PORT_16550A && up->port.iotype == UPIO_AU) | ||
2665 | up->bugs |= UART_BUG_NOMSR; | ||
2666 | |||
2585 | if (up->port.type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ) | 2667 | if (up->port.type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ) |
2586 | autoconfig_irq(up); | 2668 | autoconfig_irq(up); |
2587 | 2669 | ||
@@ -2624,6 +2706,7 @@ static struct uart_ops serial8250_pops = { | |||
2624 | .startup = serial8250_startup, | 2706 | .startup = serial8250_startup, |
2625 | .shutdown = serial8250_shutdown, | 2707 | .shutdown = serial8250_shutdown, |
2626 | .set_termios = serial8250_set_termios, | 2708 | .set_termios = serial8250_set_termios, |
2709 | .set_ldisc = serial8250_set_ldisc, | ||
2627 | .pm = serial8250_pm, | 2710 | .pm = serial8250_pm, |
2628 | .type = serial8250_type, | 2711 | .type = serial8250_type, |
2629 | .release_port = serial8250_release_port, | 2712 | .release_port = serial8250_release_port, |
@@ -2638,11 +2721,21 @@ static struct uart_ops serial8250_pops = { | |||
2638 | 2721 | ||
2639 | static struct uart_8250_port serial8250_ports[UART_NR]; | 2722 | static struct uart_8250_port serial8250_ports[UART_NR]; |
2640 | 2723 | ||
2724 | static void (*serial8250_isa_config)(int port, struct uart_port *up, | ||
2725 | unsigned short *capabilities); | ||
2726 | |||
2727 | void serial8250_set_isa_configurator( | ||
2728 | void (*v)(int port, struct uart_port *up, unsigned short *capabilities)) | ||
2729 | { | ||
2730 | serial8250_isa_config = v; | ||
2731 | } | ||
2732 | EXPORT_SYMBOL(serial8250_set_isa_configurator); | ||
2733 | |||
2641 | static void __init serial8250_isa_init_ports(void) | 2734 | static void __init serial8250_isa_init_ports(void) |
2642 | { | 2735 | { |
2643 | struct uart_8250_port *up; | 2736 | struct uart_8250_port *up; |
2644 | static int first = 1; | 2737 | static int first = 1; |
2645 | int i; | 2738 | int i, irqflag = 0; |
2646 | 2739 | ||
2647 | if (!first) | 2740 | if (!first) |
2648 | return; | 2741 | return; |
@@ -2666,11 +2759,15 @@ static void __init serial8250_isa_init_ports(void) | |||
2666 | up->port.ops = &serial8250_pops; | 2759 | up->port.ops = &serial8250_pops; |
2667 | } | 2760 | } |
2668 | 2761 | ||
2762 | if (share_irqs) | ||
2763 | irqflag = IRQF_SHARED; | ||
2764 | |||
2669 | for (i = 0, up = serial8250_ports; | 2765 | for (i = 0, up = serial8250_ports; |
2670 | i < ARRAY_SIZE(old_serial_port) && i < nr_uarts; | 2766 | i < ARRAY_SIZE(old_serial_port) && i < nr_uarts; |
2671 | i++, up++) { | 2767 | i++, up++) { |
2672 | up->port.iobase = old_serial_port[i].port; | 2768 | up->port.iobase = old_serial_port[i].port; |
2673 | up->port.irq = irq_canonicalize(old_serial_port[i].irq); | 2769 | up->port.irq = irq_canonicalize(old_serial_port[i].irq); |
2770 | up->port.irqflags = old_serial_port[i].irqflags; | ||
2674 | up->port.uartclk = old_serial_port[i].baud_base * 16; | 2771 | up->port.uartclk = old_serial_port[i].baud_base * 16; |
2675 | up->port.flags = old_serial_port[i].flags; | 2772 | up->port.flags = old_serial_port[i].flags; |
2676 | up->port.hub6 = old_serial_port[i].hub6; | 2773 | up->port.hub6 = old_serial_port[i].hub6; |
@@ -2678,11 +2775,22 @@ static void __init serial8250_isa_init_ports(void) | |||
2678 | up->port.iotype = old_serial_port[i].io_type; | 2775 | up->port.iotype = old_serial_port[i].io_type; |
2679 | up->port.regshift = old_serial_port[i].iomem_reg_shift; | 2776 | up->port.regshift = old_serial_port[i].iomem_reg_shift; |
2680 | set_io_from_upio(&up->port); | 2777 | set_io_from_upio(&up->port); |
2681 | if (share_irqs) | 2778 | up->port.irqflags |= irqflag; |
2682 | up->port.flags |= UPF_SHARE_IRQ; | 2779 | if (serial8250_isa_config != NULL) |
2780 | serial8250_isa_config(i, &up->port, &up->capabilities); | ||
2781 | |||
2683 | } | 2782 | } |
2684 | } | 2783 | } |
2685 | 2784 | ||
2785 | static void | ||
2786 | serial8250_init_fixed_type_port(struct uart_8250_port *up, unsigned int type) | ||
2787 | { | ||
2788 | up->port.type = type; | ||
2789 | up->port.fifosize = uart_config[type].fifo_size; | ||
2790 | up->capabilities = uart_config[type].flags; | ||
2791 | up->tx_loadsz = uart_config[type].tx_loadsz; | ||
2792 | } | ||
2793 | |||
2686 | static void __init | 2794 | static void __init |
2687 | serial8250_register_ports(struct uart_driver *drv, struct device *dev) | 2795 | serial8250_register_ports(struct uart_driver *drv, struct device *dev) |
2688 | { | 2796 | { |
@@ -2699,6 +2807,10 @@ serial8250_register_ports(struct uart_driver *drv, struct device *dev) | |||
2699 | struct uart_8250_port *up = &serial8250_ports[i]; | 2807 | struct uart_8250_port *up = &serial8250_ports[i]; |
2700 | 2808 | ||
2701 | up->port.dev = dev; | 2809 | up->port.dev = dev; |
2810 | |||
2811 | if (up->port.flags & UPF_FIXED_TYPE) | ||
2812 | serial8250_init_fixed_type_port(up, up->port.type); | ||
2813 | |||
2702 | uart_add_one_port(drv, &up->port); | 2814 | uart_add_one_port(drv, &up->port); |
2703 | } | 2815 | } |
2704 | } | 2816 | } |
@@ -2707,7 +2819,8 @@ serial8250_register_ports(struct uart_driver *drv, struct device *dev) | |||
2707 | 2819 | ||
2708 | static void serial8250_console_putchar(struct uart_port *port, int ch) | 2820 | static void serial8250_console_putchar(struct uart_port *port, int ch) |
2709 | { | 2821 | { |
2710 | struct uart_8250_port *up = (struct uart_8250_port *)port; | 2822 | struct uart_8250_port *up = |
2823 | container_of(port, struct uart_8250_port, port); | ||
2711 | 2824 | ||
2712 | wait_for_xmitr(up, UART_LSR_THRE); | 2825 | wait_for_xmitr(up, UART_LSR_THRE); |
2713 | serial_out(up, UART_TX, ch); | 2826 | serial_out(up, UART_TX, ch); |
@@ -2808,7 +2921,7 @@ static struct console serial8250_console = { | |||
2808 | .device = uart_console_device, | 2921 | .device = uart_console_device, |
2809 | .setup = serial8250_console_setup, | 2922 | .setup = serial8250_console_setup, |
2810 | .early_setup = serial8250_console_early_setup, | 2923 | .early_setup = serial8250_console_early_setup, |
2811 | .flags = CON_PRINTBUFFER, | 2924 | .flags = CON_PRINTBUFFER | CON_ANYTIME, |
2812 | .index = -1, | 2925 | .index = -1, |
2813 | .data = &serial8250_reg, | 2926 | .data = &serial8250_reg, |
2814 | }; | 2927 | }; |
@@ -2869,6 +2982,7 @@ int __init early_serial_setup(struct uart_port *port) | |||
2869 | p->iobase = port->iobase; | 2982 | p->iobase = port->iobase; |
2870 | p->membase = port->membase; | 2983 | p->membase = port->membase; |
2871 | p->irq = port->irq; | 2984 | p->irq = port->irq; |
2985 | p->irqflags = port->irqflags; | ||
2872 | p->uartclk = port->uartclk; | 2986 | p->uartclk = port->uartclk; |
2873 | p->fifosize = port->fifosize; | 2987 | p->fifosize = port->fifosize; |
2874 | p->regshift = port->regshift; | 2988 | p->regshift = port->regshift; |
@@ -2934,14 +3048,18 @@ static int __devinit serial8250_probe(struct platform_device *dev) | |||
2934 | { | 3048 | { |
2935 | struct plat_serial8250_port *p = dev->dev.platform_data; | 3049 | struct plat_serial8250_port *p = dev->dev.platform_data; |
2936 | struct uart_port port; | 3050 | struct uart_port port; |
2937 | int ret, i; | 3051 | int ret, i, irqflag = 0; |
2938 | 3052 | ||
2939 | memset(&port, 0, sizeof(struct uart_port)); | 3053 | memset(&port, 0, sizeof(struct uart_port)); |
2940 | 3054 | ||
3055 | if (share_irqs) | ||
3056 | irqflag = IRQF_SHARED; | ||
3057 | |||
2941 | for (i = 0; p && p->flags != 0; p++, i++) { | 3058 | for (i = 0; p && p->flags != 0; p++, i++) { |
2942 | port.iobase = p->iobase; | 3059 | port.iobase = p->iobase; |
2943 | port.membase = p->membase; | 3060 | port.membase = p->membase; |
2944 | port.irq = p->irq; | 3061 | port.irq = p->irq; |
3062 | port.irqflags = p->irqflags; | ||
2945 | port.uartclk = p->uartclk; | 3063 | port.uartclk = p->uartclk; |
2946 | port.regshift = p->regshift; | 3064 | port.regshift = p->regshift; |
2947 | port.iotype = p->iotype; | 3065 | port.iotype = p->iotype; |
@@ -2952,9 +3070,10 @@ static int __devinit serial8250_probe(struct platform_device *dev) | |||
2952 | port.type = p->type; | 3070 | port.type = p->type; |
2953 | port.serial_in = p->serial_in; | 3071 | port.serial_in = p->serial_in; |
2954 | port.serial_out = p->serial_out; | 3072 | port.serial_out = p->serial_out; |
3073 | port.set_termios = p->set_termios; | ||
3074 | port.pm = p->pm; | ||
2955 | port.dev = &dev->dev; | 3075 | port.dev = &dev->dev; |
2956 | if (share_irqs) | 3076 | port.irqflags |= irqflag; |
2957 | port.flags |= UPF_SHARE_IRQ; | ||
2958 | ret = serial8250_register_port(&port); | 3077 | ret = serial8250_register_port(&port); |
2959 | if (ret < 0) { | 3078 | if (ret < 0) { |
2960 | dev_err(&dev->dev, "unable to register port at index %d " | 3079 | dev_err(&dev->dev, "unable to register port at index %d " |
@@ -3096,6 +3215,7 @@ int serial8250_register_port(struct uart_port *port) | |||
3096 | uart->port.iobase = port->iobase; | 3215 | uart->port.iobase = port->iobase; |
3097 | uart->port.membase = port->membase; | 3216 | uart->port.membase = port->membase; |
3098 | uart->port.irq = port->irq; | 3217 | uart->port.irq = port->irq; |
3218 | uart->port.irqflags = port->irqflags; | ||
3099 | uart->port.uartclk = port->uartclk; | 3219 | uart->port.uartclk = port->uartclk; |
3100 | uart->port.fifosize = port->fifosize; | 3220 | uart->port.fifosize = port->fifosize; |
3101 | uart->port.regshift = port->regshift; | 3221 | uart->port.regshift = port->regshift; |
@@ -3106,12 +3226,8 @@ int serial8250_register_port(struct uart_port *port) | |||
3106 | if (port->dev) | 3226 | if (port->dev) |
3107 | uart->port.dev = port->dev; | 3227 | uart->port.dev = port->dev; |
3108 | 3228 | ||
3109 | if (port->flags & UPF_FIXED_TYPE) { | 3229 | if (port->flags & UPF_FIXED_TYPE) |
3110 | uart->port.type = port->type; | 3230 | serial8250_init_fixed_type_port(uart, port->type); |
3111 | uart->port.fifosize = uart_config[port->type].fifo_size; | ||
3112 | uart->capabilities = uart_config[port->type].flags; | ||
3113 | uart->tx_loadsz = uart_config[port->type].tx_loadsz; | ||
3114 | } | ||
3115 | 3231 | ||
3116 | set_io_from_upio(&uart->port); | 3232 | set_io_from_upio(&uart->port); |
3117 | /* Possibly override default I/O functions. */ | 3233 | /* Possibly override default I/O functions. */ |
@@ -3119,6 +3235,15 @@ int serial8250_register_port(struct uart_port *port) | |||
3119 | uart->port.serial_in = port->serial_in; | 3235 | uart->port.serial_in = port->serial_in; |
3120 | if (port->serial_out) | 3236 | if (port->serial_out) |
3121 | uart->port.serial_out = port->serial_out; | 3237 | uart->port.serial_out = port->serial_out; |
3238 | /* Possibly override set_termios call */ | ||
3239 | if (port->set_termios) | ||
3240 | uart->port.set_termios = port->set_termios; | ||
3241 | if (port->pm) | ||
3242 | uart->port.pm = port->pm; | ||
3243 | |||
3244 | if (serial8250_isa_config != NULL) | ||
3245 | serial8250_isa_config(0, &uart->port, | ||
3246 | &uart->capabilities); | ||
3122 | 3247 | ||
3123 | ret = uart_add_one_port(&serial8250_reg, &uart->port); | 3248 | ret = uart_add_one_port(&serial8250_reg, &uart->port); |
3124 | if (ret == 0) | 3249 | if (ret == 0) |
@@ -3242,6 +3367,9 @@ MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices" | |||
3242 | module_param(nr_uarts, uint, 0644); | 3367 | module_param(nr_uarts, uint, 0644); |
3243 | MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")"); | 3368 | MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")"); |
3244 | 3369 | ||
3370 | module_param(skip_txen_test, uint, 0644); | ||
3371 | MODULE_PARM_DESC(skip_txen_test, "Skip checking for the TXEN bug at init time"); | ||
3372 | |||
3245 | #ifdef CONFIG_SERIAL_8250_RSA | 3373 | #ifdef CONFIG_SERIAL_8250_RSA |
3246 | module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444); | 3374 | module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444); |
3247 | MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA"); | 3375 | MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA"); |
diff --git a/drivers/serial/8250.h b/drivers/serial/8250.h index 520260326f3d..6e19ea3e48d5 100644 --- a/drivers/serial/8250.h +++ b/drivers/serial/8250.h | |||
@@ -25,6 +25,7 @@ struct old_serial_port { | |||
25 | unsigned char io_type; | 25 | unsigned char io_type; |
26 | unsigned char *iomem_base; | 26 | unsigned char *iomem_base; |
27 | unsigned short iomem_reg_shift; | 27 | unsigned short iomem_reg_shift; |
28 | unsigned long irqflags; | ||
28 | }; | 29 | }; |
29 | 30 | ||
30 | /* | 31 | /* |
diff --git a/drivers/serial/8250_early.c b/drivers/serial/8250_early.c index f279745e9fef..eaafb98debed 100644 --- a/drivers/serial/8250_early.c +++ b/drivers/serial/8250_early.c | |||
@@ -19,9 +19,11 @@ | |||
19 | * The user can specify the device directly, e.g., | 19 | * The user can specify the device directly, e.g., |
20 | * earlycon=uart8250,io,0x3f8,9600n8 | 20 | * earlycon=uart8250,io,0x3f8,9600n8 |
21 | * earlycon=uart8250,mmio,0xff5e0000,115200n8 | 21 | * earlycon=uart8250,mmio,0xff5e0000,115200n8 |
22 | * earlycon=uart8250,mmio32,0xff5e0000,115200n8 | ||
22 | * or | 23 | * or |
23 | * console=uart8250,io,0x3f8,9600n8 | 24 | * console=uart8250,io,0x3f8,9600n8 |
24 | * console=uart8250,mmio,0xff5e0000,115200n8 | 25 | * console=uart8250,mmio,0xff5e0000,115200n8 |
26 | * console=uart8250,mmio32,0xff5e0000,115200n8 | ||
25 | */ | 27 | */ |
26 | 28 | ||
27 | #include <linux/tty.h> | 29 | #include <linux/tty.h> |
@@ -48,18 +50,31 @@ static struct early_serial8250_device early_device; | |||
48 | 50 | ||
49 | static unsigned int __init serial_in(struct uart_port *port, int offset) | 51 | static unsigned int __init serial_in(struct uart_port *port, int offset) |
50 | { | 52 | { |
51 | if (port->iotype == UPIO_MEM) | 53 | switch (port->iotype) { |
54 | case UPIO_MEM: | ||
52 | return readb(port->membase + offset); | 55 | return readb(port->membase + offset); |
53 | else | 56 | case UPIO_MEM32: |
57 | return readl(port->membase + (offset << 2)); | ||
58 | case UPIO_PORT: | ||
54 | return inb(port->iobase + offset); | 59 | return inb(port->iobase + offset); |
60 | default: | ||
61 | return 0; | ||
62 | } | ||
55 | } | 63 | } |
56 | 64 | ||
57 | static void __init serial_out(struct uart_port *port, int offset, int value) | 65 | static void __init serial_out(struct uart_port *port, int offset, int value) |
58 | { | 66 | { |
59 | if (port->iotype == UPIO_MEM) | 67 | switch (port->iotype) { |
68 | case UPIO_MEM: | ||
60 | writeb(value, port->membase + offset); | 69 | writeb(value, port->membase + offset); |
61 | else | 70 | break; |
71 | case UPIO_MEM32: | ||
72 | writel(value, port->membase + (offset << 2)); | ||
73 | break; | ||
74 | case UPIO_PORT: | ||
62 | outb(value, port->iobase + offset); | 75 | outb(value, port->iobase + offset); |
76 | break; | ||
77 | } | ||
63 | } | 78 | } |
64 | 79 | ||
65 | #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) | 80 | #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) |
@@ -137,15 +152,21 @@ static int __init parse_options(struct early_serial8250_device *device, | |||
137 | char *options) | 152 | char *options) |
138 | { | 153 | { |
139 | struct uart_port *port = &device->port; | 154 | struct uart_port *port = &device->port; |
140 | int mmio, length; | 155 | int mmio, mmio32, length; |
141 | 156 | ||
142 | if (!options) | 157 | if (!options) |
143 | return -ENODEV; | 158 | return -ENODEV; |
144 | 159 | ||
145 | port->uartclk = BASE_BAUD * 16; | 160 | port->uartclk = BASE_BAUD * 16; |
146 | if (!strncmp(options, "mmio,", 5)) { | 161 | |
147 | port->iotype = UPIO_MEM; | 162 | mmio = !strncmp(options, "mmio,", 5); |
148 | port->mapbase = simple_strtoul(options + 5, &options, 0); | 163 | mmio32 = !strncmp(options, "mmio32,", 7); |
164 | if (mmio || mmio32) { | ||
165 | port->iotype = (mmio ? UPIO_MEM : UPIO_MEM32); | ||
166 | port->mapbase = simple_strtoul(options + (mmio ? 5 : 7), | ||
167 | &options, 0); | ||
168 | if (mmio32) | ||
169 | port->regshift = 2; | ||
149 | #ifdef CONFIG_FIX_EARLYCON_MEM | 170 | #ifdef CONFIG_FIX_EARLYCON_MEM |
150 | set_fixmap_nocache(FIX_EARLYCON_MEM_BASE, | 171 | set_fixmap_nocache(FIX_EARLYCON_MEM_BASE, |
151 | port->mapbase & PAGE_MASK); | 172 | port->mapbase & PAGE_MASK); |
@@ -157,11 +178,10 @@ static int __init parse_options(struct early_serial8250_device *device, | |||
157 | if (!port->membase) { | 178 | if (!port->membase) { |
158 | printk(KERN_ERR "%s: Couldn't ioremap 0x%llx\n", | 179 | printk(KERN_ERR "%s: Couldn't ioremap 0x%llx\n", |
159 | __func__, | 180 | __func__, |
160 | (unsigned long long)port->mapbase); | 181 | (unsigned long long) port->mapbase); |
161 | return -ENOMEM; | 182 | return -ENOMEM; |
162 | } | 183 | } |
163 | #endif | 184 | #endif |
164 | mmio = 1; | ||
165 | } else if (!strncmp(options, "io,", 3)) { | 185 | } else if (!strncmp(options, "io,", 3)) { |
166 | port->iotype = UPIO_PORT; | 186 | port->iotype = UPIO_PORT; |
167 | port->iobase = simple_strtoul(options + 3, &options, 0); | 187 | port->iobase = simple_strtoul(options + 3, &options, 0); |
@@ -181,11 +201,18 @@ static int __init parse_options(struct early_serial8250_device *device, | |||
181 | device->baud); | 201 | device->baud); |
182 | } | 202 | } |
183 | 203 | ||
184 | printk(KERN_INFO "Early serial console at %s 0x%llx (options '%s')\n", | 204 | if (mmio || mmio32) |
185 | mmio ? "MMIO" : "I/O port", | 205 | printk(KERN_INFO |
186 | mmio ? (unsigned long long) port->mapbase | 206 | "Early serial console at MMIO%s 0x%llx (options '%s')\n", |
187 | : (unsigned long long) port->iobase, | 207 | mmio32 ? "32" : "", |
188 | device->options); | 208 | (unsigned long long)port->mapbase, |
209 | device->options); | ||
210 | else | ||
211 | printk(KERN_INFO | ||
212 | "Early serial console at I/O port 0x%lx (options '%s')\n", | ||
213 | port->iobase, | ||
214 | device->options); | ||
215 | |||
189 | return 0; | 216 | return 0; |
190 | } | 217 | } |
191 | 218 | ||
diff --git a/drivers/serial/8250_gsc.c b/drivers/serial/8250_gsc.c index 33149d982e82..d8c0ffbfa6e3 100644 --- a/drivers/serial/8250_gsc.c +++ b/drivers/serial/8250_gsc.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/serial_core.h> | 17 | #include <linux/serial_core.h> |
18 | #include <linux/signal.h> | 18 | #include <linux/signal.h> |
19 | #include <linux/slab.h> | ||
20 | #include <linux/types.h> | 19 | #include <linux/types.h> |
21 | 20 | ||
22 | #include <asm/hardware.h> | 21 | #include <asm/hardware.h> |
diff --git a/drivers/serial/8250_hp300.c b/drivers/serial/8250_hp300.c index 0e1410f2c033..c13438c93012 100644 --- a/drivers/serial/8250_hp300.c +++ b/drivers/serial/8250_hp300.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/dio.h> | 16 | #include <linux/dio.h> |
17 | #include <linux/console.h> | 17 | #include <linux/console.h> |
18 | #include <linux/slab.h> | ||
18 | #include <asm/io.h> | 19 | #include <asm/io.h> |
19 | 20 | ||
20 | #include "8250.h" | 21 | #include "8250.h" |
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index e371a9c15341..8b8930f700b5 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c | |||
@@ -60,11 +60,12 @@ struct serial_private { | |||
60 | 60 | ||
61 | static void moan_device(const char *str, struct pci_dev *dev) | 61 | static void moan_device(const char *str, struct pci_dev *dev) |
62 | { | 62 | { |
63 | printk(KERN_WARNING "%s: %s\n" | 63 | printk(KERN_WARNING |
64 | KERN_WARNING "Please send the output of lspci -vv, this\n" | 64 | "%s: %s\n" |
65 | KERN_WARNING "message (0x%04x,0x%04x,0x%04x,0x%04x), the\n" | 65 | "Please send the output of lspci -vv, this\n" |
66 | KERN_WARNING "manufacturer and name of serial board or\n" | 66 | "message (0x%04x,0x%04x,0x%04x,0x%04x), the\n" |
67 | KERN_WARNING "modem board to rmk+serial@arm.linux.org.uk.\n", | 67 | "manufacturer and name of serial board or\n" |
68 | "modem board to rmk+serial@arm.linux.org.uk.\n", | ||
68 | pci_name(dev), str, dev->vendor, dev->device, | 69 | pci_name(dev), str, dev->vendor, dev->device, |
69 | dev->subsystem_vendor, dev->subsystem_device); | 70 | dev->subsystem_vendor, dev->subsystem_device); |
70 | } | 71 | } |
@@ -398,8 +399,7 @@ static int sbs_init(struct pci_dev *dev) | |||
398 | { | 399 | { |
399 | u8 __iomem *p; | 400 | u8 __iomem *p; |
400 | 401 | ||
401 | p = ioremap_nocache(pci_resource_start(dev, 0), | 402 | p = pci_ioremap_bar(dev, 0); |
402 | pci_resource_len(dev, 0)); | ||
403 | 403 | ||
404 | if (p == NULL) | 404 | if (p == NULL) |
405 | return -ENOMEM; | 405 | return -ENOMEM; |
@@ -423,8 +423,7 @@ static void __devexit sbs_exit(struct pci_dev *dev) | |||
423 | { | 423 | { |
424 | u8 __iomem *p; | 424 | u8 __iomem *p; |
425 | 425 | ||
426 | p = ioremap_nocache(pci_resource_start(dev, 0), | 426 | p = pci_ioremap_bar(dev, 0); |
427 | pci_resource_len(dev, 0)); | ||
428 | /* FIXME: What if resource_len < OCT_REG_CR_OFF */ | 427 | /* FIXME: What if resource_len < OCT_REG_CR_OFF */ |
429 | if (p != NULL) | 428 | if (p != NULL) |
430 | writeb(0, p + OCT_REG_CR_OFF); | 429 | writeb(0, p + OCT_REG_CR_OFF); |
@@ -761,6 +760,9 @@ static int pci_netmos_init(struct pci_dev *dev) | |||
761 | /* subdevice 0x00PS means <P> parallel, <S> serial */ | 760 | /* subdevice 0x00PS means <P> parallel, <S> serial */ |
762 | unsigned int num_serial = dev->subsystem_device & 0xf; | 761 | unsigned int num_serial = dev->subsystem_device & 0xf; |
763 | 762 | ||
763 | if ((dev->device == PCI_DEVICE_ID_NETMOS_9901) || | ||
764 | (dev->device == PCI_DEVICE_ID_NETMOS_9865)) | ||
765 | return 0; | ||
764 | if (dev->subsystem_vendor == PCI_VENDOR_ID_IBM && | 766 | if (dev->subsystem_vendor == PCI_VENDOR_ID_IBM && |
765 | dev->subsystem_device == 0x0299) | 767 | dev->subsystem_device == 0x0299) |
766 | return 0; | 768 | return 0; |
@@ -955,6 +957,22 @@ pci_default_setup(struct serial_private *priv, | |||
955 | return setup_port(priv, port, bar, offset, board->reg_shift); | 957 | return setup_port(priv, port, bar, offset, board->reg_shift); |
956 | } | 958 | } |
957 | 959 | ||
960 | static int | ||
961 | ce4100_serial_setup(struct serial_private *priv, | ||
962 | const struct pciserial_board *board, | ||
963 | struct uart_port *port, int idx) | ||
964 | { | ||
965 | int ret; | ||
966 | |||
967 | ret = setup_port(priv, port, 0, 0, board->reg_shift); | ||
968 | port->iotype = UPIO_MEM32; | ||
969 | port->type = PORT_XSCALE; | ||
970 | port->flags = (port->flags | UPF_FIXED_PORT | UPF_FIXED_TYPE); | ||
971 | port->regshift = 2; | ||
972 | |||
973 | return ret; | ||
974 | } | ||
975 | |||
958 | static int skip_tx_en_setup(struct serial_private *priv, | 976 | static int skip_tx_en_setup(struct serial_private *priv, |
959 | const struct pciserial_board *board, | 977 | const struct pciserial_board *board, |
960 | struct uart_port *port, int idx) | 978 | struct uart_port *port, int idx) |
@@ -979,7 +997,21 @@ static int skip_tx_en_setup(struct serial_private *priv, | |||
979 | #define PCI_SUBDEVICE_ID_POCTAL232 0x0308 | 997 | #define PCI_SUBDEVICE_ID_POCTAL232 0x0308 |
980 | #define PCI_SUBDEVICE_ID_POCTAL422 0x0408 | 998 | #define PCI_SUBDEVICE_ID_POCTAL422 0x0408 |
981 | #define PCI_VENDOR_ID_ADVANTECH 0x13fe | 999 | #define PCI_VENDOR_ID_ADVANTECH 0x13fe |
1000 | #define PCI_DEVICE_ID_INTEL_CE4100_UART 0x2e66 | ||
982 | #define PCI_DEVICE_ID_ADVANTECH_PCI3620 0x3620 | 1001 | #define PCI_DEVICE_ID_ADVANTECH_PCI3620 0x3620 |
1002 | #define PCI_DEVICE_ID_TITAN_200I 0x8028 | ||
1003 | #define PCI_DEVICE_ID_TITAN_400I 0x8048 | ||
1004 | #define PCI_DEVICE_ID_TITAN_800I 0x8088 | ||
1005 | #define PCI_DEVICE_ID_TITAN_800EH 0xA007 | ||
1006 | #define PCI_DEVICE_ID_TITAN_800EHB 0xA008 | ||
1007 | #define PCI_DEVICE_ID_TITAN_400EH 0xA009 | ||
1008 | #define PCI_DEVICE_ID_TITAN_100E 0xA010 | ||
1009 | #define PCI_DEVICE_ID_TITAN_200E 0xA012 | ||
1010 | #define PCI_DEVICE_ID_TITAN_400E 0xA013 | ||
1011 | #define PCI_DEVICE_ID_TITAN_800E 0xA014 | ||
1012 | #define PCI_DEVICE_ID_TITAN_200EI 0xA016 | ||
1013 | #define PCI_DEVICE_ID_TITAN_200EISI 0xA017 | ||
1014 | #define PCI_DEVICE_ID_OXSEMI_16PCI958 0x9538 | ||
983 | 1015 | ||
984 | /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ | 1016 | /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ |
985 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 | 1017 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 |
@@ -1057,6 +1089,13 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1057 | .subdevice = PCI_ANY_ID, | 1089 | .subdevice = PCI_ANY_ID, |
1058 | .setup = skip_tx_en_setup, | 1090 | .setup = skip_tx_en_setup, |
1059 | }, | 1091 | }, |
1092 | { | ||
1093 | .vendor = PCI_VENDOR_ID_INTEL, | ||
1094 | .device = PCI_DEVICE_ID_INTEL_CE4100_UART, | ||
1095 | .subvendor = PCI_ANY_ID, | ||
1096 | .subdevice = PCI_ANY_ID, | ||
1097 | .setup = ce4100_serial_setup, | ||
1098 | }, | ||
1060 | /* | 1099 | /* |
1061 | * ITE | 1100 | * ITE |
1062 | */ | 1101 | */ |
@@ -1478,6 +1517,7 @@ enum pci_board_num_t { | |||
1478 | 1517 | ||
1479 | pbn_b0_bt_1_115200, | 1518 | pbn_b0_bt_1_115200, |
1480 | pbn_b0_bt_2_115200, | 1519 | pbn_b0_bt_2_115200, |
1520 | pbn_b0_bt_4_115200, | ||
1481 | pbn_b0_bt_8_115200, | 1521 | pbn_b0_bt_8_115200, |
1482 | 1522 | ||
1483 | pbn_b0_bt_1_460800, | 1523 | pbn_b0_bt_1_460800, |
@@ -1527,6 +1567,8 @@ enum pci_board_num_t { | |||
1527 | pbn_b2_4_921600, | 1567 | pbn_b2_4_921600, |
1528 | pbn_b2_8_921600, | 1568 | pbn_b2_8_921600, |
1529 | 1569 | ||
1570 | pbn_b2_8_1152000, | ||
1571 | |||
1530 | pbn_b2_bt_1_115200, | 1572 | pbn_b2_bt_1_115200, |
1531 | pbn_b2_bt_2_115200, | 1573 | pbn_b2_bt_2_115200, |
1532 | pbn_b2_bt_4_115200, | 1574 | pbn_b2_bt_4_115200, |
@@ -1538,6 +1580,10 @@ enum pci_board_num_t { | |||
1538 | pbn_b3_4_115200, | 1580 | pbn_b3_4_115200, |
1539 | pbn_b3_8_115200, | 1581 | pbn_b3_8_115200, |
1540 | 1582 | ||
1583 | pbn_b4_bt_2_921600, | ||
1584 | pbn_b4_bt_4_921600, | ||
1585 | pbn_b4_bt_8_921600, | ||
1586 | |||
1541 | /* | 1587 | /* |
1542 | * Board-specific versions. | 1588 | * Board-specific versions. |
1543 | */ | 1589 | */ |
@@ -1560,11 +1606,17 @@ enum pci_board_num_t { | |||
1560 | pbn_exar_XR17C152, | 1606 | pbn_exar_XR17C152, |
1561 | pbn_exar_XR17C154, | 1607 | pbn_exar_XR17C154, |
1562 | pbn_exar_XR17C158, | 1608 | pbn_exar_XR17C158, |
1609 | pbn_exar_ibm_saturn, | ||
1563 | pbn_pasemi_1682M, | 1610 | pbn_pasemi_1682M, |
1564 | pbn_ni8430_2, | 1611 | pbn_ni8430_2, |
1565 | pbn_ni8430_4, | 1612 | pbn_ni8430_4, |
1566 | pbn_ni8430_8, | 1613 | pbn_ni8430_8, |
1567 | pbn_ni8430_16, | 1614 | pbn_ni8430_16, |
1615 | pbn_ADDIDATA_PCIe_1_3906250, | ||
1616 | pbn_ADDIDATA_PCIe_2_3906250, | ||
1617 | pbn_ADDIDATA_PCIe_4_3906250, | ||
1618 | pbn_ADDIDATA_PCIe_8_3906250, | ||
1619 | pbn_ce4100_1_115200, | ||
1568 | }; | 1620 | }; |
1569 | 1621 | ||
1570 | /* | 1622 | /* |
@@ -1697,6 +1749,12 @@ static struct pciserial_board pci_boards[] __devinitdata = { | |||
1697 | .base_baud = 115200, | 1749 | .base_baud = 115200, |
1698 | .uart_offset = 8, | 1750 | .uart_offset = 8, |
1699 | }, | 1751 | }, |
1752 | [pbn_b0_bt_4_115200] = { | ||
1753 | .flags = FL_BASE0|FL_BASE_BARS, | ||
1754 | .num_ports = 4, | ||
1755 | .base_baud = 115200, | ||
1756 | .uart_offset = 8, | ||
1757 | }, | ||
1700 | [pbn_b0_bt_8_115200] = { | 1758 | [pbn_b0_bt_8_115200] = { |
1701 | .flags = FL_BASE0|FL_BASE_BARS, | 1759 | .flags = FL_BASE0|FL_BASE_BARS, |
1702 | .num_ports = 8, | 1760 | .num_ports = 8, |
@@ -1930,6 +1988,13 @@ static struct pciserial_board pci_boards[] __devinitdata = { | |||
1930 | .uart_offset = 8, | 1988 | .uart_offset = 8, |
1931 | }, | 1989 | }, |
1932 | 1990 | ||
1991 | [pbn_b2_8_1152000] = { | ||
1992 | .flags = FL_BASE2, | ||
1993 | .num_ports = 8, | ||
1994 | .base_baud = 1152000, | ||
1995 | .uart_offset = 8, | ||
1996 | }, | ||
1997 | |||
1933 | [pbn_b2_bt_1_115200] = { | 1998 | [pbn_b2_bt_1_115200] = { |
1934 | .flags = FL_BASE2|FL_BASE_BARS, | 1999 | .flags = FL_BASE2|FL_BASE_BARS, |
1935 | .num_ports = 1, | 2000 | .num_ports = 1, |
@@ -1981,6 +2046,25 @@ static struct pciserial_board pci_boards[] __devinitdata = { | |||
1981 | .uart_offset = 8, | 2046 | .uart_offset = 8, |
1982 | }, | 2047 | }, |
1983 | 2048 | ||
2049 | [pbn_b4_bt_2_921600] = { | ||
2050 | .flags = FL_BASE4, | ||
2051 | .num_ports = 2, | ||
2052 | .base_baud = 921600, | ||
2053 | .uart_offset = 8, | ||
2054 | }, | ||
2055 | [pbn_b4_bt_4_921600] = { | ||
2056 | .flags = FL_BASE4, | ||
2057 | .num_ports = 4, | ||
2058 | .base_baud = 921600, | ||
2059 | .uart_offset = 8, | ||
2060 | }, | ||
2061 | [pbn_b4_bt_8_921600] = { | ||
2062 | .flags = FL_BASE4, | ||
2063 | .num_ports = 8, | ||
2064 | .base_baud = 921600, | ||
2065 | .uart_offset = 8, | ||
2066 | }, | ||
2067 | |||
1984 | /* | 2068 | /* |
1985 | * Entries following this are board-specific. | 2069 | * Entries following this are board-specific. |
1986 | */ | 2070 | */ |
@@ -2145,6 +2229,13 @@ static struct pciserial_board pci_boards[] __devinitdata = { | |||
2145 | .base_baud = 921600, | 2229 | .base_baud = 921600, |
2146 | .uart_offset = 0x200, | 2230 | .uart_offset = 0x200, |
2147 | }, | 2231 | }, |
2232 | [pbn_exar_ibm_saturn] = { | ||
2233 | .flags = FL_BASE0, | ||
2234 | .num_ports = 1, | ||
2235 | .base_baud = 921600, | ||
2236 | .uart_offset = 0x200, | ||
2237 | }, | ||
2238 | |||
2148 | /* | 2239 | /* |
2149 | * PA Semi PWRficient PA6T-1682M on-chip UART | 2240 | * PA Semi PWRficient PA6T-1682M on-chip UART |
2150 | */ | 2241 | */ |
@@ -2184,10 +2275,49 @@ static struct pciserial_board pci_boards[] __devinitdata = { | |||
2184 | .uart_offset = 0x10, | 2275 | .uart_offset = 0x10, |
2185 | .first_offset = 0x800, | 2276 | .first_offset = 0x800, |
2186 | }, | 2277 | }, |
2278 | /* | ||
2279 | * ADDI-DATA GmbH PCI-Express communication cards <info@addi-data.com> | ||
2280 | */ | ||
2281 | [pbn_ADDIDATA_PCIe_1_3906250] = { | ||
2282 | .flags = FL_BASE0, | ||
2283 | .num_ports = 1, | ||
2284 | .base_baud = 3906250, | ||
2285 | .uart_offset = 0x200, | ||
2286 | .first_offset = 0x1000, | ||
2287 | }, | ||
2288 | [pbn_ADDIDATA_PCIe_2_3906250] = { | ||
2289 | .flags = FL_BASE0, | ||
2290 | .num_ports = 2, | ||
2291 | .base_baud = 3906250, | ||
2292 | .uart_offset = 0x200, | ||
2293 | .first_offset = 0x1000, | ||
2294 | }, | ||
2295 | [pbn_ADDIDATA_PCIe_4_3906250] = { | ||
2296 | .flags = FL_BASE0, | ||
2297 | .num_ports = 4, | ||
2298 | .base_baud = 3906250, | ||
2299 | .uart_offset = 0x200, | ||
2300 | .first_offset = 0x1000, | ||
2301 | }, | ||
2302 | [pbn_ADDIDATA_PCIe_8_3906250] = { | ||
2303 | .flags = FL_BASE0, | ||
2304 | .num_ports = 8, | ||
2305 | .base_baud = 3906250, | ||
2306 | .uart_offset = 0x200, | ||
2307 | .first_offset = 0x1000, | ||
2308 | }, | ||
2309 | [pbn_ce4100_1_115200] = { | ||
2310 | .flags = FL_BASE0, | ||
2311 | .num_ports = 1, | ||
2312 | .base_baud = 921600, | ||
2313 | .reg_shift = 2, | ||
2314 | }, | ||
2187 | }; | 2315 | }; |
2188 | 2316 | ||
2189 | static const struct pci_device_id softmodem_blacklist[] = { | 2317 | static const struct pci_device_id softmodem_blacklist[] = { |
2190 | { PCI_VDEVICE(AL, 0x5457), }, /* ALi Corporation M5457 AC'97 Modem */ | 2318 | { PCI_VDEVICE(AL, 0x5457), }, /* ALi Corporation M5457 AC'97 Modem */ |
2319 | { PCI_VDEVICE(MOTOROLA, 0x3052), }, /* Motorola Si3052-based modem */ | ||
2320 | { PCI_DEVICE(0x1543, 0x3052), }, /* Si3052-based modem, default IDs */ | ||
2191 | }; | 2321 | }; |
2192 | 2322 | ||
2193 | /* | 2323 | /* |
@@ -2339,7 +2469,7 @@ pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board) | |||
2339 | break; | 2469 | break; |
2340 | 2470 | ||
2341 | #ifdef SERIAL_DEBUG_PCI | 2471 | #ifdef SERIAL_DEBUG_PCI |
2342 | printk(KERN_DEBUG "Setup PCI port: port %x, irq %d, type %d\n", | 2472 | printk(KERN_DEBUG "Setup PCI port: port %lx, irq %d, type %d\n", |
2343 | serial_port.iobase, serial_port.irq, serial_port.iotype); | 2473 | serial_port.iobase, serial_port.irq, serial_port.iotype); |
2344 | #endif | 2474 | #endif |
2345 | 2475 | ||
@@ -2648,6 +2778,9 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
2648 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 2778 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
2649 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_485, 0, 0, | 2779 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_485, 0, 0, |
2650 | pbn_b0_8_1843200_200 }, | 2780 | pbn_b0_8_1843200_200 }, |
2781 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, | ||
2782 | PCI_VENDOR_ID_IBM, PCI_SUBDEVICE_ID_IBM_SATURN_SERIAL_ONE_PORT, | ||
2783 | 0, 0, pbn_exar_ibm_saturn }, | ||
2651 | 2784 | ||
2652 | { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_U530, | 2785 | { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_U530, |
2653 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 2786 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
@@ -2763,6 +2896,9 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
2763 | PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL, | 2896 | PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL, |
2764 | 0, 0, | 2897 | 0, 0, |
2765 | pbn_b0_4_1152000 }, | 2898 | pbn_b0_4_1152000 }, |
2899 | { PCI_VENDOR_ID_OXSEMI, 0x9505, | ||
2900 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
2901 | pbn_b0_bt_2_921600 }, | ||
2766 | 2902 | ||
2767 | /* | 2903 | /* |
2768 | * The below card is a little controversial since it is the | 2904 | * The below card is a little controversial since it is the |
@@ -2785,6 +2921,9 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
2785 | { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI952, | 2921 | { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI952, |
2786 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 2922 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
2787 | pbn_b0_bt_2_921600 }, | 2923 | pbn_b0_bt_2_921600 }, |
2924 | { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI958, | ||
2925 | PCI_ANY_ID , PCI_ANY_ID, 0, 0, | ||
2926 | pbn_b2_8_1152000 }, | ||
2788 | 2927 | ||
2789 | /* | 2928 | /* |
2790 | * Oxford Semiconductor Inc. Tornado PCI express device range. | 2929 | * Oxford Semiconductor Inc. Tornado PCI express device range. |
@@ -2988,6 +3127,42 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
2988 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800L, | 3127 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800L, |
2989 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 3128 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
2990 | pbn_b0_bt_8_921600 }, | 3129 | pbn_b0_bt_8_921600 }, |
3130 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200I, | ||
3131 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3132 | pbn_b4_bt_2_921600 }, | ||
3133 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400I, | ||
3134 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3135 | pbn_b4_bt_4_921600 }, | ||
3136 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800I, | ||
3137 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3138 | pbn_b4_bt_8_921600 }, | ||
3139 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400EH, | ||
3140 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3141 | pbn_b0_4_921600 }, | ||
3142 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800EH, | ||
3143 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3144 | pbn_b0_4_921600 }, | ||
3145 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800EHB, | ||
3146 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3147 | pbn_b0_4_921600 }, | ||
3148 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100E, | ||
3149 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3150 | pbn_oxsemi_1_4000000 }, | ||
3151 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200E, | ||
3152 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3153 | pbn_oxsemi_2_4000000 }, | ||
3154 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400E, | ||
3155 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3156 | pbn_oxsemi_4_4000000 }, | ||
3157 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800E, | ||
3158 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3159 | pbn_oxsemi_8_4000000 }, | ||
3160 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200EI, | ||
3161 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3162 | pbn_oxsemi_2_4000000 }, | ||
3163 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200EISI, | ||
3164 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3165 | pbn_oxsemi_2_4000000 }, | ||
2991 | 3166 | ||
2992 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_550, | 3167 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_550, |
2993 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 3168 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
@@ -3092,6 +3267,12 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
3092 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_B, | 3267 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_B, |
3093 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 3268 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
3094 | pbn_b0_bt_2_115200 }, | 3269 | pbn_b0_bt_2_115200 }, |
3270 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATTRO_A, | ||
3271 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3272 | pbn_b0_bt_2_115200 }, | ||
3273 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATTRO_B, | ||
3274 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3275 | pbn_b0_bt_2_115200 }, | ||
3095 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_OCTO_A, | 3276 | { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_OCTO_A, |
3096 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 3277 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
3097 | pbn_b0_bt_4_460800 }, | 3278 | pbn_b0_bt_4_460800 }, |
@@ -3138,6 +3319,15 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
3138 | 0x1208, 0x0004, 0, 0, | 3319 | 0x1208, 0x0004, 0, 0, |
3139 | pbn_b0_4_921600 }, | 3320 | pbn_b0_4_921600 }, |
3140 | 3321 | ||
3322 | { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF2, | ||
3323 | 0x1204, 0x0004, 0, 0, | ||
3324 | pbn_b0_4_921600 }, | ||
3325 | { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF2, | ||
3326 | 0x1208, 0x0004, 0, 0, | ||
3327 | pbn_b0_4_921600 }, | ||
3328 | { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF3, | ||
3329 | 0x1208, 0x0004, 0, 0, | ||
3330 | pbn_b0_4_921600 }, | ||
3141 | /* | 3331 | /* |
3142 | * Dell Remote Access Card 4 - Tim_T_Murphy@Dell.com | 3332 | * Dell Remote Access Card 4 - Tim_T_Murphy@Dell.com |
3143 | */ | 3333 | */ |
@@ -3555,10 +3745,63 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
3555 | 0, | 3745 | 0, |
3556 | pbn_b0_8_115200 }, | 3746 | pbn_b0_8_115200 }, |
3557 | 3747 | ||
3748 | { PCI_VENDOR_ID_ADDIDATA, | ||
3749 | PCI_DEVICE_ID_ADDIDATA_APCIe7500, | ||
3750 | PCI_ANY_ID, | ||
3751 | PCI_ANY_ID, | ||
3752 | 0, | ||
3753 | 0, | ||
3754 | pbn_ADDIDATA_PCIe_4_3906250 }, | ||
3755 | |||
3756 | { PCI_VENDOR_ID_ADDIDATA, | ||
3757 | PCI_DEVICE_ID_ADDIDATA_APCIe7420, | ||
3758 | PCI_ANY_ID, | ||
3759 | PCI_ANY_ID, | ||
3760 | 0, | ||
3761 | 0, | ||
3762 | pbn_ADDIDATA_PCIe_2_3906250 }, | ||
3763 | |||
3764 | { PCI_VENDOR_ID_ADDIDATA, | ||
3765 | PCI_DEVICE_ID_ADDIDATA_APCIe7300, | ||
3766 | PCI_ANY_ID, | ||
3767 | PCI_ANY_ID, | ||
3768 | 0, | ||
3769 | 0, | ||
3770 | pbn_ADDIDATA_PCIe_1_3906250 }, | ||
3771 | |||
3772 | { PCI_VENDOR_ID_ADDIDATA, | ||
3773 | PCI_DEVICE_ID_ADDIDATA_APCIe7800, | ||
3774 | PCI_ANY_ID, | ||
3775 | PCI_ANY_ID, | ||
3776 | 0, | ||
3777 | 0, | ||
3778 | pbn_ADDIDATA_PCIe_8_3906250 }, | ||
3779 | |||
3558 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835, | 3780 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835, |
3559 | PCI_VENDOR_ID_IBM, 0x0299, | 3781 | PCI_VENDOR_ID_IBM, 0x0299, |
3560 | 0, 0, pbn_b0_bt_2_115200 }, | 3782 | 0, 0, pbn_b0_bt_2_115200 }, |
3561 | 3783 | ||
3784 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9901, | ||
3785 | 0xA000, 0x1000, | ||
3786 | 0, 0, pbn_b0_1_115200 }, | ||
3787 | |||
3788 | /* | ||
3789 | * Best Connectivity PCI Multi I/O cards | ||
3790 | */ | ||
3791 | |||
3792 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865, | ||
3793 | 0xA000, 0x1000, | ||
3794 | 0, 0, pbn_b0_1_115200 }, | ||
3795 | |||
3796 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865, | ||
3797 | 0xA000, 0x3004, | ||
3798 | 0, 0, pbn_b0_bt_4_115200 }, | ||
3799 | /* Intel CE4100 */ | ||
3800 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CE4100_UART, | ||
3801 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3802 | pbn_ce4100_1_115200 }, | ||
3803 | |||
3804 | |||
3562 | /* | 3805 | /* |
3563 | * These entries match devices with class COMMUNICATION_SERIAL, | 3806 | * These entries match devices with class COMMUNICATION_SERIAL, |
3564 | * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL | 3807 | * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL |
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c index d71dfe398940..4822cb50cd0f 100644 --- a/drivers/serial/8250_pnp.c +++ b/drivers/serial/8250_pnp.c | |||
@@ -328,15 +328,7 @@ static const struct pnp_device_id pnp_dev_table[] = { | |||
328 | /* U.S. Robotics 56K Voice INT PnP*/ | 328 | /* U.S. Robotics 56K Voice INT PnP*/ |
329 | { "USR9190", 0 }, | 329 | { "USR9190", 0 }, |
330 | /* Wacom tablets */ | 330 | /* Wacom tablets */ |
331 | { "WACF004", 0 }, | 331 | { "WACFXXX", 0 }, |
332 | { "WACF005", 0 }, | ||
333 | { "WACF006", 0 }, | ||
334 | { "WACF007", 0 }, | ||
335 | { "WACF008", 0 }, | ||
336 | { "WACF009", 0 }, | ||
337 | { "WACF00A", 0 }, | ||
338 | { "WACF00B", 0 }, | ||
339 | { "WACF00C", 0 }, | ||
340 | /* Compaq touchscreen */ | 332 | /* Compaq touchscreen */ |
341 | { "FPI2002", 0 }, | 333 | { "FPI2002", 0 }, |
342 | /* Fujitsu Stylistic touchscreens */ | 334 | /* Fujitsu Stylistic touchscreens */ |
@@ -354,6 +346,10 @@ static const struct pnp_device_id pnp_dev_table[] = { | |||
354 | { "FUJ02E5", 0 }, | 346 | { "FUJ02E5", 0 }, |
355 | /* Fujitsu P-series tablet PC device */ | 347 | /* Fujitsu P-series tablet PC device */ |
356 | { "FUJ02E6", 0 }, | 348 | { "FUJ02E6", 0 }, |
349 | /* Fujitsu Wacom 2FGT Tablet PC device */ | ||
350 | { "FUJ02E7", 0 }, | ||
351 | /* Fujitsu Wacom 1FGT Tablet PC device */ | ||
352 | { "FUJ02E9", 0 }, | ||
357 | /* | 353 | /* |
358 | * LG C1 EXPRESS DUAL (C1-PB11A3) touch screen (actually a FUJ02E6 in | 354 | * LG C1 EXPRESS DUAL (C1-PB11A3) touch screen (actually a FUJ02E6 in |
359 | * disguise) | 355 | * disguise) |
@@ -361,9 +357,9 @@ static const struct pnp_device_id pnp_dev_table[] = { | |||
361 | { "LTS0001", 0 }, | 357 | { "LTS0001", 0 }, |
362 | /* Rockwell's (PORALiNK) 33600 INT PNP */ | 358 | /* Rockwell's (PORALiNK) 33600 INT PNP */ |
363 | { "WCI0003", 0 }, | 359 | { "WCI0003", 0 }, |
364 | /* Unkown PnP modems */ | 360 | /* Unknown PnP modems */ |
365 | { "PNPCXXX", UNKNOWN_DEV }, | 361 | { "PNPCXXX", UNKNOWN_DEV }, |
366 | /* More unkown PnP modems */ | 362 | /* More unknown PnP modems */ |
367 | { "PNPDXXX", UNKNOWN_DEV }, | 363 | { "PNPDXXX", UNKNOWN_DEV }, |
368 | { "", 0 } | 364 | { "", 0 } |
369 | }; | 365 | }; |
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 037c1e0b7c4c..c1df7676a73d 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig | |||
@@ -258,14 +258,6 @@ config SERIAL_8250_ACORN | |||
258 | system, say Y to this option. The driver can handle 1, 2, or 3 port | 258 | system, say Y to this option. The driver can handle 1, 2, or 3 port |
259 | cards. If unsure, say N. | 259 | cards. If unsure, say N. |
260 | 260 | ||
261 | config SERIAL_8250_AU1X00 | ||
262 | bool "Au1x00 serial port support" | ||
263 | depends on SERIAL_8250 != n && SOC_AU1X00 | ||
264 | help | ||
265 | If you have an Au1x00 SOC based board and want to use the serial port, | ||
266 | say Y to this option. The driver can handle up to 4 serial ports, | ||
267 | depending on the SOC. If unsure, say N. | ||
268 | |||
269 | config SERIAL_8250_RM9K | 261 | config SERIAL_8250_RM9K |
270 | bool "Support for MIPS RM9xxx integrated serial port" | 262 | bool "Support for MIPS RM9xxx integrated serial port" |
271 | depends on SERIAL_8250 != n && SERIAL_RM9000 | 263 | depends on SERIAL_8250 != n && SERIAL_RM9000 |
@@ -447,7 +439,7 @@ config SERIAL_CLPS711X_CONSOLE | |||
447 | 439 | ||
448 | config SERIAL_SAMSUNG | 440 | config SERIAL_SAMSUNG |
449 | tristate "Samsung SoC serial support" | 441 | tristate "Samsung SoC serial support" |
450 | depends on ARM && PLAT_S3C | 442 | depends on ARM && PLAT_SAMSUNG |
451 | select SERIAL_CORE | 443 | select SERIAL_CORE |
452 | help | 444 | help |
453 | Support for the on-chip UARTs on the Samsung S3C24XX series CPUs, | 445 | Support for the on-chip UARTs on the Samsung S3C24XX series CPUs, |
@@ -455,11 +447,19 @@ config SERIAL_SAMSUNG | |||
455 | provide all of these ports, depending on how the serial port | 447 | provide all of these ports, depending on how the serial port |
456 | pins are configured. | 448 | pins are configured. |
457 | 449 | ||
450 | config SERIAL_SAMSUNG_UARTS_4 | ||
451 | bool | ||
452 | depends on ARM && PLAT_SAMSUNG | ||
453 | default y if CPU_S3C2443 | ||
454 | help | ||
455 | Internal node for the common case of 4 Samsung compatible UARTs | ||
456 | |||
458 | config SERIAL_SAMSUNG_UARTS | 457 | config SERIAL_SAMSUNG_UARTS |
459 | int | 458 | int |
460 | depends on ARM && PLAT_S3C | 459 | depends on ARM && PLAT_SAMSUNG |
461 | default 2 if ARCH_S3C2400 | 460 | default 2 if ARCH_S3C2400 |
462 | default 4 if ARCH_S3C64XX || CPU_S3C2443 | 461 | default 6 if ARCH_S5P6450 |
462 | default 4 if SERIAL_SAMSUNG_UARTS_4 | ||
463 | default 3 | 463 | default 3 |
464 | help | 464 | help |
465 | Select the number of available UART ports for the Samsung S3C | 465 | Select the number of available UART ports for the Samsung S3C |
@@ -511,12 +511,13 @@ config SERIAL_S3C2412 | |||
511 | Serial port support for the Samsung S3C2412 and S3C2413 SoC | 511 | Serial port support for the Samsung S3C2412 and S3C2413 SoC |
512 | 512 | ||
513 | config SERIAL_S3C2440 | 513 | config SERIAL_S3C2440 |
514 | tristate "Samsung S3C2440/S3C2442 Serial port support" | 514 | tristate "Samsung S3C2440/S3C2442/S3C2416 Serial port support" |
515 | depends on SERIAL_SAMSUNG && (CPU_S3C2440 || CPU_S3C2442) | 515 | depends on SERIAL_SAMSUNG && (CPU_S3C2440 || CPU_S3C2442 || CPU_S3C2416) |
516 | default y if CPU_S3C2440 | 516 | default y if CPU_S3C2440 |
517 | default y if CPU_S3C2442 | 517 | default y if CPU_S3C2442 |
518 | select SERIAL_SAMSUNG_UARTS_4 if CPU_S3C2416 | ||
518 | help | 519 | help |
519 | Serial port support for the Samsung S3C2440 and S3C2442 SoC | 520 | Serial port support for the Samsung S3C2440, S3C2416 and S3C2442 SoC |
520 | 521 | ||
521 | config SERIAL_S3C24A0 | 522 | config SERIAL_S3C24A0 |
522 | tristate "Samsung S3C24A0 Serial port support" | 523 | tristate "Samsung S3C24A0 Serial port support" |
@@ -526,12 +527,22 @@ config SERIAL_S3C24A0 | |||
526 | Serial port support for the Samsung S3C24A0 SoC | 527 | Serial port support for the Samsung S3C24A0 SoC |
527 | 528 | ||
528 | config SERIAL_S3C6400 | 529 | config SERIAL_S3C6400 |
529 | tristate "Samsung S3C6400/S3C6410 Serial port support" | 530 | tristate "Samsung S3C6400/S3C6410/S5P6440/S5P6450/S5PC100 Serial port support" |
530 | depends on SERIAL_SAMSUNG && (CPU_S3C600 || CPU_S3C6410) | 531 | depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410 || CPU_S5P6440 || CPU_S5P6450 || CPU_S5PC100) |
532 | select SERIAL_SAMSUNG_UARTS_4 | ||
533 | default y | ||
534 | help | ||
535 | Serial port support for the Samsung S3C6400, S3C6410, S5P6440, S5P6450 | ||
536 | and S5PC100 SoCs | ||
537 | |||
538 | config SERIAL_S5PV210 | ||
539 | tristate "Samsung S5PV210 Serial port support" | ||
540 | depends on SERIAL_SAMSUNG && (CPU_S5PV210 || CPU_S5P6442 || CPU_S5PV310) | ||
541 | select SERIAL_SAMSUNG_UARTS_4 if (CPU_S5PV210 || CPU_S5PV310) | ||
531 | default y | 542 | default y |
532 | help | 543 | help |
533 | Serial port support for the Samsung S3C6400 and S3C6410 | 544 | Serial port support for Samsung's S5P Family of SoC's |
534 | SoCs | 545 | |
535 | 546 | ||
536 | config SERIAL_MAX3100 | 547 | config SERIAL_MAX3100 |
537 | tristate "MAX3100 support" | 548 | tristate "MAX3100 support" |
@@ -540,6 +551,22 @@ config SERIAL_MAX3100 | |||
540 | help | 551 | help |
541 | MAX3100 chip support | 552 | MAX3100 chip support |
542 | 553 | ||
554 | config SERIAL_MAX3107 | ||
555 | tristate "MAX3107 support" | ||
556 | depends on SPI | ||
557 | select SERIAL_CORE | ||
558 | help | ||
559 | MAX3107 chip support | ||
560 | |||
561 | config SERIAL_MAX3107_AAVA | ||
562 | tristate "MAX3107 AAVA platform support" | ||
563 | depends on X86_MRST && SERIAL_MAX3107 && GPIOLIB | ||
564 | select SERIAL_CORE | ||
565 | help | ||
566 | Support for the MAX3107 chip configuration found on the AAVA | ||
567 | platform. Includes the extra initialisation and GPIO support | ||
568 | neded for this device. | ||
569 | |||
543 | config SERIAL_DZ | 570 | config SERIAL_DZ |
544 | bool "DECstation DZ serial driver" | 571 | bool "DECstation DZ serial driver" |
545 | depends on MACH_DECSTATION && 32BIT | 572 | depends on MACH_DECSTATION && 32BIT |
@@ -681,6 +708,26 @@ config SERIAL_SA1100_CONSOLE | |||
681 | your boot loader (lilo or loadlin) about how to pass options to the | 708 | your boot loader (lilo or loadlin) about how to pass options to the |
682 | kernel at boot time.) | 709 | kernel at boot time.) |
683 | 710 | ||
711 | config SERIAL_MRST_MAX3110 | ||
712 | tristate "SPI UART driver for Max3110" | ||
713 | depends on SPI_DW_PCI | ||
714 | select SERIAL_CORE | ||
715 | select SERIAL_CORE_CONSOLE | ||
716 | help | ||
717 | This is the UART protocol driver for the MAX3110 device on | ||
718 | the Intel Moorestown platform. On other systems use the max3100 | ||
719 | driver. | ||
720 | |||
721 | config SERIAL_MFD_HSU | ||
722 | tristate "Medfield High Speed UART support" | ||
723 | depends on PCI | ||
724 | select SERIAL_CORE | ||
725 | |||
726 | config SERIAL_MFD_HSU_CONSOLE | ||
727 | boolean "Medfile HSU serial console support" | ||
728 | depends on SERIAL_MFD_HSU=y | ||
729 | select SERIAL_CORE_CONSOLE | ||
730 | |||
684 | config SERIAL_BFIN | 731 | config SERIAL_BFIN |
685 | tristate "Blackfin serial port support" | 732 | tristate "Blackfin serial port support" |
686 | depends on BLACKFIN | 733 | depends on BLACKFIN |
@@ -729,24 +776,7 @@ config BFIN_UART0_CTSRTS | |||
729 | bool "Enable UART0 hardware flow control" | 776 | bool "Enable UART0 hardware flow control" |
730 | depends on SERIAL_BFIN_UART0 | 777 | depends on SERIAL_BFIN_UART0 |
731 | help | 778 | help |
732 | Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS | 779 | Enable hardware flow control in the driver. |
733 | signal. | ||
734 | |||
735 | config UART0_CTS_PIN | ||
736 | int "UART0 CTS pin" | ||
737 | depends on BFIN_UART0_CTSRTS && !BF548 | ||
738 | default 23 | ||
739 | help | ||
740 | The default pin is GPIO_GP7. | ||
741 | Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map. | ||
742 | |||
743 | config UART0_RTS_PIN | ||
744 | int "UART0 RTS pin" | ||
745 | depends on BFIN_UART0_CTSRTS && !BF548 | ||
746 | default 22 | ||
747 | help | ||
748 | The default pin is GPIO_GP6. | ||
749 | Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map. | ||
750 | 780 | ||
751 | config SERIAL_BFIN_UART1 | 781 | config SERIAL_BFIN_UART1 |
752 | bool "Enable UART1" | 782 | bool "Enable UART1" |
@@ -758,22 +788,7 @@ config BFIN_UART1_CTSRTS | |||
758 | bool "Enable UART1 hardware flow control" | 788 | bool "Enable UART1 hardware flow control" |
759 | depends on SERIAL_BFIN_UART1 | 789 | depends on SERIAL_BFIN_UART1 |
760 | help | 790 | help |
761 | Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS | 791 | Enable hardware flow control in the driver. |
762 | signal. | ||
763 | |||
764 | config UART1_CTS_PIN | ||
765 | int "UART1 CTS pin" | ||
766 | depends on BFIN_UART1_CTSRTS && !BF548 | ||
767 | default -1 | ||
768 | help | ||
769 | Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map. | ||
770 | |||
771 | config UART1_RTS_PIN | ||
772 | int "UART1 RTS pin" | ||
773 | depends on BFIN_UART1_CTSRTS && !BF548 | ||
774 | default -1 | ||
775 | help | ||
776 | Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map. | ||
777 | 792 | ||
778 | config SERIAL_BFIN_UART2 | 793 | config SERIAL_BFIN_UART2 |
779 | bool "Enable UART2" | 794 | bool "Enable UART2" |
@@ -785,22 +800,7 @@ config BFIN_UART2_CTSRTS | |||
785 | bool "Enable UART2 hardware flow control" | 800 | bool "Enable UART2 hardware flow control" |
786 | depends on SERIAL_BFIN_UART2 | 801 | depends on SERIAL_BFIN_UART2 |
787 | help | 802 | help |
788 | Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS | 803 | Enable hardware flow control in the driver. |
789 | signal. | ||
790 | |||
791 | config UART2_CTS_PIN | ||
792 | int "UART2 CTS pin" | ||
793 | depends on BFIN_UART2_CTSRTS && !BF548 | ||
794 | default -1 | ||
795 | help | ||
796 | Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map. | ||
797 | |||
798 | config UART2_RTS_PIN | ||
799 | int "UART2 RTS pin" | ||
800 | depends on BFIN_UART2_CTSRTS && !BF548 | ||
801 | default -1 | ||
802 | help | ||
803 | Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map. | ||
804 | 804 | ||
805 | config SERIAL_BFIN_UART3 | 805 | config SERIAL_BFIN_UART3 |
806 | bool "Enable UART3" | 806 | bool "Enable UART3" |
@@ -812,22 +812,7 @@ config BFIN_UART3_CTSRTS | |||
812 | bool "Enable UART3 hardware flow control" | 812 | bool "Enable UART3 hardware flow control" |
813 | depends on SERIAL_BFIN_UART3 | 813 | depends on SERIAL_BFIN_UART3 |
814 | help | 814 | help |
815 | Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS | 815 | Enable hardware flow control in the driver. |
816 | signal. | ||
817 | |||
818 | config UART3_CTS_PIN | ||
819 | int "UART3 CTS pin" | ||
820 | depends on BFIN_UART3_CTSRTS && !BF548 | ||
821 | default -1 | ||
822 | help | ||
823 | Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map. | ||
824 | |||
825 | config UART3_RTS_PIN | ||
826 | int "UART3 RTS pin" | ||
827 | depends on BFIN_UART3_CTSRTS && !BF548 | ||
828 | default -1 | ||
829 | help | ||
830 | Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map. | ||
831 | 816 | ||
832 | config SERIAL_IMX | 817 | config SERIAL_IMX |
833 | bool "IMX serial port support" | 818 | bool "IMX serial port support" |
@@ -855,7 +840,7 @@ config SERIAL_IMX_CONSOLE | |||
855 | 840 | ||
856 | config SERIAL_UARTLITE | 841 | config SERIAL_UARTLITE |
857 | tristate "Xilinx uartlite serial port support" | 842 | tristate "Xilinx uartlite serial port support" |
858 | depends on PPC32 || MICROBLAZE | 843 | depends on PPC32 || MICROBLAZE || MFD_TIMBERDALE |
859 | select SERIAL_CORE | 844 | select SERIAL_CORE |
860 | help | 845 | help |
861 | Say Y here if you want to use the Xilinx uartlite serial controller. | 846 | Say Y here if you want to use the Xilinx uartlite serial controller. |
@@ -989,7 +974,7 @@ config SERIAL_IP22_ZILOG_CONSOLE | |||
989 | 974 | ||
990 | config SERIAL_SH_SCI | 975 | config SERIAL_SH_SCI |
991 | tristate "SuperH SCI(F) serial port support" | 976 | tristate "SuperH SCI(F) serial port support" |
992 | depends on SUPERH || H8300 | 977 | depends on HAVE_CLK && (SUPERH || H8300 || ARCH_SHMOBILE) |
993 | select SERIAL_CORE | 978 | select SERIAL_CORE |
994 | 979 | ||
995 | config SERIAL_SH_SCI_NR_UARTS | 980 | config SERIAL_SH_SCI_NR_UARTS |
@@ -1002,6 +987,10 @@ config SERIAL_SH_SCI_CONSOLE | |||
1002 | depends on SERIAL_SH_SCI=y | 987 | depends on SERIAL_SH_SCI=y |
1003 | select SERIAL_CORE_CONSOLE | 988 | select SERIAL_CORE_CONSOLE |
1004 | 989 | ||
990 | config SERIAL_SH_SCI_DMA | ||
991 | bool "DMA support" | ||
992 | depends on SERIAL_SH_SCI && SH_DMAE && EXPERIMENTAL | ||
993 | |||
1005 | config SERIAL_PNX8XXX | 994 | config SERIAL_PNX8XXX |
1006 | bool "Enable PNX8XXX SoCs' UART Support" | 995 | bool "Enable PNX8XXX SoCs' UART Support" |
1007 | depends on MIPS && (SOC_PNX8550 || SOC_PNX833X) | 996 | depends on MIPS && (SOC_PNX8550 || SOC_PNX833X) |
@@ -1079,12 +1068,12 @@ config SERIAL_68360 | |||
1079 | default y | 1068 | default y |
1080 | 1069 | ||
1081 | config SERIAL_PMACZILOG | 1070 | config SERIAL_PMACZILOG |
1082 | tristate "PowerMac z85c30 ESCC support" | 1071 | tristate "Mac or PowerMac z85c30 ESCC support" |
1083 | depends on PPC_OF && PPC_PMAC | 1072 | depends on (M68K && MAC) || (PPC_OF && PPC_PMAC) |
1084 | select SERIAL_CORE | 1073 | select SERIAL_CORE |
1085 | help | 1074 | help |
1086 | This driver supports the Zilog z85C30 serial ports found on | 1075 | This driver supports the Zilog z85C30 serial ports found on |
1087 | PowerMac machines. | 1076 | (Power)Mac machines. |
1088 | Say Y or M if you want to be able to these serial ports. | 1077 | Say Y or M if you want to be able to these serial ports. |
1089 | 1078 | ||
1090 | config SERIAL_PMACZILOG_TTYS | 1079 | config SERIAL_PMACZILOG_TTYS |
@@ -1109,16 +1098,16 @@ config SERIAL_PMACZILOG_TTYS | |||
1109 | unable to use the 8250 module for PCMCIA or other 16C550-style | 1098 | unable to use the 8250 module for PCMCIA or other 16C550-style |
1110 | UARTs. | 1099 | UARTs. |
1111 | 1100 | ||
1112 | Say N unless you need the z85c30 ports on your powermac | 1101 | Say N unless you need the z85c30 ports on your (Power)Mac |
1113 | to appear as /dev/ttySn. | 1102 | to appear as /dev/ttySn. |
1114 | 1103 | ||
1115 | config SERIAL_PMACZILOG_CONSOLE | 1104 | config SERIAL_PMACZILOG_CONSOLE |
1116 | bool "Console on PowerMac z85c30 serial port" | 1105 | bool "Console on Mac or PowerMac z85c30 serial port" |
1117 | depends on SERIAL_PMACZILOG=y | 1106 | depends on SERIAL_PMACZILOG=y |
1118 | select SERIAL_CORE_CONSOLE | 1107 | select SERIAL_CORE_CONSOLE |
1119 | help | 1108 | help |
1120 | If you would like to be able to use the z85c30 serial port | 1109 | If you would like to be able to use the z85c30 serial port |
1121 | on your PowerMac as the console, you can do so by answering | 1110 | on your (Power)Mac as the console, you can do so by answering |
1122 | Y to this option. | 1111 | Y to this option. |
1123 | 1112 | ||
1124 | config SERIAL_LH7A40X | 1113 | config SERIAL_LH7A40X |
@@ -1330,6 +1319,16 @@ config SERIAL_MSM_CONSOLE | |||
1330 | depends on SERIAL_MSM=y | 1319 | depends on SERIAL_MSM=y |
1331 | select SERIAL_CORE_CONSOLE | 1320 | select SERIAL_CORE_CONSOLE |
1332 | 1321 | ||
1322 | config SERIAL_VT8500 | ||
1323 | bool "VIA VT8500 on-chip serial port support" | ||
1324 | depends on ARM && ARCH_VT8500 | ||
1325 | select SERIAL_CORE | ||
1326 | |||
1327 | config SERIAL_VT8500_CONSOLE | ||
1328 | bool "VIA VT8500 serial console support" | ||
1329 | depends on SERIAL_VT8500=y | ||
1330 | select SERIAL_CORE_CONSOLE | ||
1331 | |||
1333 | config SERIAL_NETX | 1332 | config SERIAL_NETX |
1334 | tristate "NetX serial port support" | 1333 | tristate "NetX serial port support" |
1335 | depends on ARM && ARCH_NETX | 1334 | depends on ARM && ARCH_NETX |
@@ -1351,7 +1350,7 @@ config SERIAL_NETX_CONSOLE | |||
1351 | 1350 | ||
1352 | config SERIAL_OF_PLATFORM | 1351 | config SERIAL_OF_PLATFORM |
1353 | tristate "Serial port on Open Firmware platform bus" | 1352 | tristate "Serial port on Open Firmware platform bus" |
1354 | depends on PPC_OF || MICROBLAZE | 1353 | depends on OF |
1355 | depends on SERIAL_8250 || SERIAL_OF_PLATFORM_NWPSERIAL | 1354 | depends on SERIAL_8250 || SERIAL_OF_PLATFORM_NWPSERIAL |
1356 | help | 1355 | help |
1357 | If you have a PowerPC based system that has serial ports | 1356 | If you have a PowerPC based system that has serial ports |
@@ -1359,6 +1358,33 @@ config SERIAL_OF_PLATFORM | |||
1359 | Currently, only 8250 compatible ports are supported, but | 1358 | Currently, only 8250 compatible ports are supported, but |
1360 | others can easily be added. | 1359 | others can easily be added. |
1361 | 1360 | ||
1361 | config SERIAL_OMAP | ||
1362 | tristate "OMAP serial port support" | ||
1363 | depends on ARCH_OMAP2 || ARCH_OMAP3 || ARCH_OMAP4 | ||
1364 | select SERIAL_CORE | ||
1365 | help | ||
1366 | If you have a machine based on an Texas Instruments OMAP CPU you | ||
1367 | can enable its onboard serial ports by enabling this option. | ||
1368 | |||
1369 | By enabling this option you take advantage of dma feature available | ||
1370 | with the omap-serial driver. DMA support can be enabled from platform | ||
1371 | data. | ||
1372 | |||
1373 | config SERIAL_OMAP_CONSOLE | ||
1374 | bool "Console on OMAP serial port" | ||
1375 | depends on SERIAL_OMAP | ||
1376 | select SERIAL_CORE_CONSOLE | ||
1377 | help | ||
1378 | Select this option if you would like to use omap serial port as | ||
1379 | console. | ||
1380 | |||
1381 | Even if you say Y here, the currently visible virtual console | ||
1382 | (/dev/tty0) will still be used as the system console by default, but | ||
1383 | you can alter that using a kernel command line option such as | ||
1384 | "console=ttyOx". (Try "man bootparam" or see the documentation of | ||
1385 | your boot loader about how to pass options to the kernel at | ||
1386 | boot time.) | ||
1387 | |||
1362 | config SERIAL_OF_PLATFORM_NWPSERIAL | 1388 | config SERIAL_OF_PLATFORM_NWPSERIAL |
1363 | tristate "NWP serial port driver" | 1389 | tristate "NWP serial port driver" |
1364 | depends on PPC_OF && PPC_DCR | 1390 | depends on PPC_OF && PPC_DCR |
@@ -1402,8 +1428,8 @@ config SERIAL_SC26XX_CONSOLE | |||
1402 | Support for Console on SC2681/SC2692 serial ports. | 1428 | Support for Console on SC2681/SC2692 serial ports. |
1403 | 1429 | ||
1404 | config SERIAL_BFIN_SPORT | 1430 | config SERIAL_BFIN_SPORT |
1405 | tristate "Blackfin SPORT emulate UART (EXPERIMENTAL)" | 1431 | tristate "Blackfin SPORT emulate UART" |
1406 | depends on BLACKFIN && EXPERIMENTAL | 1432 | depends on BLACKFIN |
1407 | select SERIAL_CORE | 1433 | select SERIAL_CORE |
1408 | help | 1434 | help |
1409 | Enable SPORT emulate UART on Blackfin series. | 1435 | Enable SPORT emulate UART on Blackfin series. |
@@ -1411,44 +1437,162 @@ config SERIAL_BFIN_SPORT | |||
1411 | To compile this driver as a module, choose M here: the | 1437 | To compile this driver as a module, choose M here: the |
1412 | module will be called bfin_sport_uart. | 1438 | module will be called bfin_sport_uart. |
1413 | 1439 | ||
1414 | choice | 1440 | config SERIAL_BFIN_SPORT_CONSOLE |
1415 | prompt "Baud rate for Blackfin SPORT UART" | 1441 | bool "Console on Blackfin sport emulated uart" |
1416 | depends on SERIAL_BFIN_SPORT | 1442 | depends on SERIAL_BFIN_SPORT=y |
1417 | default SERIAL_SPORT_BAUD_RATE_57600 | 1443 | select SERIAL_CORE_CONSOLE |
1444 | |||
1445 | config SERIAL_BFIN_SPORT0_UART | ||
1446 | bool "Enable UART over SPORT0" | ||
1447 | depends on SERIAL_BFIN_SPORT && !(BF542 || BF544) | ||
1418 | help | 1448 | help |
1419 | Choose a baud rate for the SPORT UART, other uart settings are | 1449 | Enable UART over SPORT0 |
1420 | 8 bit, 1 stop bit, no parity, no flow control. | ||
1421 | 1450 | ||
1422 | config SERIAL_SPORT_BAUD_RATE_115200 | 1451 | config SERIAL_BFIN_SPORT0_UART_CTSRTS |
1423 | bool "115200" | 1452 | bool "Enable UART over SPORT0 hardware flow control" |
1453 | depends on SERIAL_BFIN_SPORT0_UART | ||
1454 | help | ||
1455 | Enable hardware flow control in the driver. | ||
1424 | 1456 | ||
1425 | config SERIAL_SPORT_BAUD_RATE_57600 | 1457 | config SERIAL_BFIN_SPORT1_UART |
1426 | bool "57600" | 1458 | bool "Enable UART over SPORT1" |
1459 | depends on SERIAL_BFIN_SPORT | ||
1460 | help | ||
1461 | Enable UART over SPORT1 | ||
1427 | 1462 | ||
1428 | config SERIAL_SPORT_BAUD_RATE_38400 | 1463 | config SERIAL_BFIN_SPORT1_UART_CTSRTS |
1429 | bool "38400" | 1464 | bool "Enable UART over SPORT1 hardware flow control" |
1465 | depends on SERIAL_BFIN_SPORT1_UART | ||
1466 | help | ||
1467 | Enable hardware flow control in the driver. | ||
1430 | 1468 | ||
1431 | config SERIAL_SPORT_BAUD_RATE_19200 | 1469 | config SERIAL_BFIN_SPORT2_UART |
1432 | bool "19200" | 1470 | bool "Enable UART over SPORT2" |
1471 | depends on SERIAL_BFIN_SPORT && (BF54x || BF538 || BF539) | ||
1472 | help | ||
1473 | Enable UART over SPORT2 | ||
1433 | 1474 | ||
1434 | config SERIAL_SPORT_BAUD_RATE_9600 | 1475 | config SERIAL_BFIN_SPORT2_UART_CTSRTS |
1435 | bool "9600" | 1476 | bool "Enable UART over SPORT2 hardware flow control" |
1436 | endchoice | 1477 | depends on SERIAL_BFIN_SPORT2_UART |
1478 | help | ||
1479 | Enable hardware flow control in the driver. | ||
1437 | 1480 | ||
1438 | config SPORT_BAUD_RATE | 1481 | config SERIAL_BFIN_SPORT3_UART |
1439 | int | 1482 | bool "Enable UART over SPORT3" |
1440 | depends on SERIAL_BFIN_SPORT | 1483 | depends on SERIAL_BFIN_SPORT && (BF54x || BF538 || BF539) |
1441 | default 115200 if (SERIAL_SPORT_BAUD_RATE_115200) | 1484 | help |
1442 | default 57600 if (SERIAL_SPORT_BAUD_RATE_57600) | 1485 | Enable UART over SPORT3 |
1443 | default 38400 if (SERIAL_SPORT_BAUD_RATE_38400) | 1486 | |
1444 | default 19200 if (SERIAL_SPORT_BAUD_RATE_19200) | 1487 | config SERIAL_BFIN_SPORT3_UART_CTSRTS |
1445 | default 9600 if (SERIAL_SPORT_BAUD_RATE_9600) | 1488 | bool "Enable UART over SPORT3 hardware flow control" |
1489 | depends on SERIAL_BFIN_SPORT3_UART | ||
1490 | help | ||
1491 | Enable hardware flow control in the driver. | ||
1446 | 1492 | ||
1447 | config SERIAL_TIMBERDALE | 1493 | config SERIAL_TIMBERDALE |
1448 | tristate "Support for timberdale UART" | 1494 | tristate "Support for timberdale UART" |
1449 | depends on MFD_TIMBERDALE | ||
1450 | select SERIAL_CORE | 1495 | select SERIAL_CORE |
1451 | ---help--- | 1496 | ---help--- |
1452 | Add support for UART controller on timberdale. | 1497 | Add support for UART controller on timberdale. |
1453 | 1498 | ||
1499 | config SERIAL_BCM63XX | ||
1500 | tristate "bcm63xx serial port support" | ||
1501 | select SERIAL_CORE | ||
1502 | depends on BCM63XX | ||
1503 | help | ||
1504 | If you have a bcm63xx CPU, you can enable its onboard | ||
1505 | serial port by enabling this options. | ||
1506 | |||
1507 | To compile this driver as a module, choose M here: the | ||
1508 | module will be called bcm963xx_uart. | ||
1509 | |||
1510 | config SERIAL_BCM63XX_CONSOLE | ||
1511 | bool "Console on bcm63xx serial port" | ||
1512 | depends on SERIAL_BCM63XX=y | ||
1513 | select SERIAL_CORE_CONSOLE | ||
1514 | help | ||
1515 | If you have enabled the serial port on the bcm63xx CPU | ||
1516 | you can make it the console by answering Y to this option. | ||
1517 | |||
1518 | config SERIAL_GRLIB_GAISLER_APBUART | ||
1519 | tristate "GRLIB APBUART serial support" | ||
1520 | depends on OF | ||
1521 | ---help--- | ||
1522 | Add support for the GRLIB APBUART serial port. | ||
1523 | |||
1524 | config SERIAL_GRLIB_GAISLER_APBUART_CONSOLE | ||
1525 | bool "Console on GRLIB APBUART serial port" | ||
1526 | depends on SERIAL_GRLIB_GAISLER_APBUART=y | ||
1527 | select SERIAL_CORE_CONSOLE | ||
1528 | help | ||
1529 | Support for running a console on the GRLIB APBUART | ||
1530 | |||
1531 | config SERIAL_ALTERA_JTAGUART | ||
1532 | tristate "Altera JTAG UART support" | ||
1533 | select SERIAL_CORE | ||
1534 | help | ||
1535 | This driver supports the Altera JTAG UART port. | ||
1536 | |||
1537 | config SERIAL_ALTERA_JTAGUART_CONSOLE | ||
1538 | bool "Altera JTAG UART console support" | ||
1539 | depends on SERIAL_ALTERA_JTAGUART=y | ||
1540 | select SERIAL_CORE_CONSOLE | ||
1541 | help | ||
1542 | Enable a Altera JTAG UART port to be the system console. | ||
1543 | |||
1544 | config SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS | ||
1545 | bool "Bypass output when no connection" | ||
1546 | depends on SERIAL_ALTERA_JTAGUART_CONSOLE | ||
1547 | select SERIAL_CORE_CONSOLE | ||
1548 | help | ||
1549 | Bypass console output and keep going even if there is no | ||
1550 | JTAG terminal connection with the host. | ||
1551 | |||
1552 | config SERIAL_ALTERA_UART | ||
1553 | tristate "Altera UART support" | ||
1554 | select SERIAL_CORE | ||
1555 | help | ||
1556 | This driver supports the Altera softcore UART port. | ||
1557 | |||
1558 | config SERIAL_ALTERA_UART_MAXPORTS | ||
1559 | int "Maximum number of Altera UART ports" | ||
1560 | depends on SERIAL_ALTERA_UART | ||
1561 | default 4 | ||
1562 | help | ||
1563 | This setting lets you define the maximum number of the Altera | ||
1564 | UART ports. The usual default varies from board to board, and | ||
1565 | this setting is a way of catering for that. | ||
1566 | |||
1567 | config SERIAL_ALTERA_UART_BAUDRATE | ||
1568 | int "Default baudrate for Altera UART ports" | ||
1569 | depends on SERIAL_ALTERA_UART | ||
1570 | default 115200 | ||
1571 | help | ||
1572 | This setting lets you define what the default baudrate is for the | ||
1573 | Altera UART ports. The usual default varies from board to board, | ||
1574 | and this setting is a way of catering for that. | ||
1575 | |||
1576 | config SERIAL_ALTERA_UART_CONSOLE | ||
1577 | bool "Altera UART console support" | ||
1578 | depends on SERIAL_ALTERA_UART=y | ||
1579 | select SERIAL_CORE_CONSOLE | ||
1580 | help | ||
1581 | Enable a Altera UART port to be the system console. | ||
1582 | |||
1583 | config SERIAL_IFX6X60 | ||
1584 | tristate "SPI protocol driver for Infineon 6x60 modem (EXPERIMENTAL)" | ||
1585 | depends on GPIOLIB && SPI && EXPERIMENTAL | ||
1586 | help | ||
1587 | Support for the IFX6x60 modem devices on Intel MID platforms. | ||
1588 | |||
1589 | config SERIAL_PCH_UART | ||
1590 | tristate "Intel EG20T PCH UART" | ||
1591 | depends on PCI && DMADEVICES | ||
1592 | select SERIAL_CORE | ||
1593 | select PCH_DMA | ||
1594 | help | ||
1595 | This driver is for PCH(Platform controller Hub) UART of Intel EG20T | ||
1596 | which is an IOH(Input/Output Hub) for x86 embedded processor. | ||
1597 | Enabling PCH_DMA, this PCH UART works as DMA mode. | ||
1454 | endmenu | 1598 | endmenu |
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index d5a29981c6c4..8ea92e9c73b0 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile | |||
@@ -34,6 +34,7 @@ obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o | |||
34 | obj-$(CONFIG_SERIAL_PXA) += pxa.o | 34 | obj-$(CONFIG_SERIAL_PXA) += pxa.o |
35 | obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o | 35 | obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o |
36 | obj-$(CONFIG_SERIAL_SA1100) += sa1100.o | 36 | obj-$(CONFIG_SERIAL_SA1100) += sa1100.o |
37 | obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o | ||
37 | obj-$(CONFIG_SERIAL_BFIN) += bfin_5xx.o | 38 | obj-$(CONFIG_SERIAL_BFIN) += bfin_5xx.o |
38 | obj-$(CONFIG_SERIAL_BFIN_SPORT) += bfin_sport_uart.o | 39 | obj-$(CONFIG_SERIAL_BFIN_SPORT) += bfin_sport_uart.o |
39 | obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o | 40 | obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o |
@@ -43,7 +44,10 @@ obj-$(CONFIG_SERIAL_S3C2412) += s3c2412.o | |||
43 | obj-$(CONFIG_SERIAL_S3C2440) += s3c2440.o | 44 | obj-$(CONFIG_SERIAL_S3C2440) += s3c2440.o |
44 | obj-$(CONFIG_SERIAL_S3C24A0) += s3c24a0.o | 45 | obj-$(CONFIG_SERIAL_S3C24A0) += s3c24a0.o |
45 | obj-$(CONFIG_SERIAL_S3C6400) += s3c6400.o | 46 | obj-$(CONFIG_SERIAL_S3C6400) += s3c6400.o |
47 | obj-$(CONFIG_SERIAL_S5PV210) += s5pv210.o | ||
46 | obj-$(CONFIG_SERIAL_MAX3100) += max3100.o | 48 | obj-$(CONFIG_SERIAL_MAX3100) += max3100.o |
49 | obj-$(CONFIG_SERIAL_MAX3107) += max3107.o | ||
50 | obj-$(CONFIG_SERIAL_MAX3107_AAVA) += max3107-aava.o | ||
47 | obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o | 51 | obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o |
48 | obj-$(CONFIG_SERIAL_MUX) += mux.o | 52 | obj-$(CONFIG_SERIAL_MUX) += mux.o |
49 | obj-$(CONFIG_SERIAL_68328) += 68328serial.o | 53 | obj-$(CONFIG_SERIAL_68328) += 68328serial.o |
@@ -76,6 +80,15 @@ obj-$(CONFIG_SERIAL_NETX) += netx-serial.o | |||
76 | obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o | 80 | obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o |
77 | obj-$(CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL) += nwpserial.o | 81 | obj-$(CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL) += nwpserial.o |
78 | obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o | 82 | obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o |
83 | obj-$(CONFIG_SERIAL_OMAP) += omap-serial.o | ||
79 | obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o | 84 | obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o |
80 | obj-$(CONFIG_SERIAL_QE) += ucc_uart.o | 85 | obj-$(CONFIG_SERIAL_QE) += ucc_uart.o |
81 | obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o | 86 | obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o |
87 | obj-$(CONFIG_SERIAL_GRLIB_GAISLER_APBUART) += apbuart.o | ||
88 | obj-$(CONFIG_SERIAL_ALTERA_JTAGUART) += altera_jtaguart.o | ||
89 | obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o | ||
90 | obj-$(CONFIG_SERIAL_VT8500) += vt8500_serial.o | ||
91 | obj-$(CONFIG_SERIAL_MRST_MAX3110) += mrst_max3110.o | ||
92 | obj-$(CONFIG_SERIAL_MFD_HSU) += mfd.o | ||
93 | obj-$(CONFIG_SERIAL_IFX6X60) += ifx6x60.o | ||
94 | obj-$(CONFIG_SERIAL_PCH_UART) += pch_uart.o | ||
diff --git a/drivers/serial/altera_jtaguart.c b/drivers/serial/altera_jtaguart.c new file mode 100644 index 000000000000..f9b49b5ff5e1 --- /dev/null +++ b/drivers/serial/altera_jtaguart.c | |||
@@ -0,0 +1,504 @@ | |||
1 | /* | ||
2 | * altera_jtaguart.c -- Altera JTAG UART driver | ||
3 | * | ||
4 | * Based on mcf.c -- Freescale ColdFire UART driver | ||
5 | * | ||
6 | * (C) Copyright 2003-2007, Greg Ungerer <gerg@snapgear.com> | ||
7 | * (C) Copyright 2008, Thomas Chou <thomas@wytron.com.tw> | ||
8 | * (C) Copyright 2010, Tobias Klauser <tklauser@distanz.ch> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/console.h> | ||
21 | #include <linux/tty.h> | ||
22 | #include <linux/tty_flip.h> | ||
23 | #include <linux/serial.h> | ||
24 | #include <linux/serial_core.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/io.h> | ||
27 | #include <linux/altera_jtaguart.h> | ||
28 | |||
29 | #define DRV_NAME "altera_jtaguart" | ||
30 | |||
31 | /* | ||
32 | * Altera JTAG UART register definitions according to the Altera JTAG UART | ||
33 | * datasheet: http://www.altera.com/literature/hb/nios2/n2cpu_nii51009.pdf | ||
34 | */ | ||
35 | |||
36 | #define ALTERA_JTAGUART_SIZE 8 | ||
37 | |||
38 | #define ALTERA_JTAGUART_DATA_REG 0 | ||
39 | |||
40 | #define ALTERA_JTAGUART_DATA_DATA_MSK 0x000000FF | ||
41 | #define ALTERA_JTAGUART_DATA_RVALID_MSK 0x00008000 | ||
42 | #define ALTERA_JTAGUART_DATA_RAVAIL_MSK 0xFFFF0000 | ||
43 | #define ALTERA_JTAGUART_DATA_RAVAIL_OFF 16 | ||
44 | |||
45 | #define ALTERA_JTAGUART_CONTROL_REG 4 | ||
46 | |||
47 | #define ALTERA_JTAGUART_CONTROL_RE_MSK 0x00000001 | ||
48 | #define ALTERA_JTAGUART_CONTROL_WE_MSK 0x00000002 | ||
49 | #define ALTERA_JTAGUART_CONTROL_RI_MSK 0x00000100 | ||
50 | #define ALTERA_JTAGUART_CONTROL_RI_OFF 8 | ||
51 | #define ALTERA_JTAGUART_CONTROL_WI_MSK 0x00000200 | ||
52 | #define ALTERA_JTAGUART_CONTROL_AC_MSK 0x00000400 | ||
53 | #define ALTERA_JTAGUART_CONTROL_WSPACE_MSK 0xFFFF0000 | ||
54 | #define ALTERA_JTAGUART_CONTROL_WSPACE_OFF 16 | ||
55 | |||
56 | /* | ||
57 | * Local per-uart structure. | ||
58 | */ | ||
59 | struct altera_jtaguart { | ||
60 | struct uart_port port; | ||
61 | unsigned int sigs; /* Local copy of line sigs */ | ||
62 | unsigned long imr; /* Local IMR mirror */ | ||
63 | }; | ||
64 | |||
65 | static unsigned int altera_jtaguart_tx_empty(struct uart_port *port) | ||
66 | { | ||
67 | return (readl(port->membase + ALTERA_JTAGUART_CONTROL_REG) & | ||
68 | ALTERA_JTAGUART_CONTROL_WSPACE_MSK) ? TIOCSER_TEMT : 0; | ||
69 | } | ||
70 | |||
71 | static unsigned int altera_jtaguart_get_mctrl(struct uart_port *port) | ||
72 | { | ||
73 | return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; | ||
74 | } | ||
75 | |||
76 | static void altera_jtaguart_set_mctrl(struct uart_port *port, unsigned int sigs) | ||
77 | { | ||
78 | } | ||
79 | |||
80 | static void altera_jtaguart_start_tx(struct uart_port *port) | ||
81 | { | ||
82 | struct altera_jtaguart *pp = | ||
83 | container_of(port, struct altera_jtaguart, port); | ||
84 | |||
85 | pp->imr |= ALTERA_JTAGUART_CONTROL_WE_MSK; | ||
86 | writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG); | ||
87 | } | ||
88 | |||
89 | static void altera_jtaguart_stop_tx(struct uart_port *port) | ||
90 | { | ||
91 | struct altera_jtaguart *pp = | ||
92 | container_of(port, struct altera_jtaguart, port); | ||
93 | |||
94 | pp->imr &= ~ALTERA_JTAGUART_CONTROL_WE_MSK; | ||
95 | writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG); | ||
96 | } | ||
97 | |||
98 | static void altera_jtaguart_stop_rx(struct uart_port *port) | ||
99 | { | ||
100 | struct altera_jtaguart *pp = | ||
101 | container_of(port, struct altera_jtaguart, port); | ||
102 | |||
103 | pp->imr &= ~ALTERA_JTAGUART_CONTROL_RE_MSK; | ||
104 | writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG); | ||
105 | } | ||
106 | |||
107 | static void altera_jtaguart_break_ctl(struct uart_port *port, int break_state) | ||
108 | { | ||
109 | } | ||
110 | |||
111 | static void altera_jtaguart_enable_ms(struct uart_port *port) | ||
112 | { | ||
113 | } | ||
114 | |||
115 | static void altera_jtaguart_set_termios(struct uart_port *port, | ||
116 | struct ktermios *termios, | ||
117 | struct ktermios *old) | ||
118 | { | ||
119 | /* Just copy the old termios settings back */ | ||
120 | if (old) | ||
121 | tty_termios_copy_hw(termios, old); | ||
122 | } | ||
123 | |||
124 | static void altera_jtaguart_rx_chars(struct altera_jtaguart *pp) | ||
125 | { | ||
126 | struct uart_port *port = &pp->port; | ||
127 | unsigned char ch, flag; | ||
128 | unsigned long status; | ||
129 | |||
130 | while ((status = readl(port->membase + ALTERA_JTAGUART_DATA_REG)) & | ||
131 | ALTERA_JTAGUART_DATA_RVALID_MSK) { | ||
132 | ch = status & ALTERA_JTAGUART_DATA_DATA_MSK; | ||
133 | flag = TTY_NORMAL; | ||
134 | port->icount.rx++; | ||
135 | |||
136 | if (uart_handle_sysrq_char(port, ch)) | ||
137 | continue; | ||
138 | uart_insert_char(port, 0, 0, ch, flag); | ||
139 | } | ||
140 | |||
141 | tty_flip_buffer_push(port->state->port.tty); | ||
142 | } | ||
143 | |||
144 | static void altera_jtaguart_tx_chars(struct altera_jtaguart *pp) | ||
145 | { | ||
146 | struct uart_port *port = &pp->port; | ||
147 | struct circ_buf *xmit = &port->state->xmit; | ||
148 | unsigned int pending, count; | ||
149 | |||
150 | if (port->x_char) { | ||
151 | /* Send special char - probably flow control */ | ||
152 | writel(port->x_char, port->membase + ALTERA_JTAGUART_DATA_REG); | ||
153 | port->x_char = 0; | ||
154 | port->icount.tx++; | ||
155 | return; | ||
156 | } | ||
157 | |||
158 | pending = uart_circ_chars_pending(xmit); | ||
159 | if (pending > 0) { | ||
160 | count = (readl(port->membase + ALTERA_JTAGUART_CONTROL_REG) & | ||
161 | ALTERA_JTAGUART_CONTROL_WSPACE_MSK) >> | ||
162 | ALTERA_JTAGUART_CONTROL_WSPACE_OFF; | ||
163 | if (count > pending) | ||
164 | count = pending; | ||
165 | if (count > 0) { | ||
166 | pending -= count; | ||
167 | while (count--) { | ||
168 | writel(xmit->buf[xmit->tail], | ||
169 | port->membase + ALTERA_JTAGUART_DATA_REG); | ||
170 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
171 | port->icount.tx++; | ||
172 | } | ||
173 | if (pending < WAKEUP_CHARS) | ||
174 | uart_write_wakeup(port); | ||
175 | } | ||
176 | } | ||
177 | |||
178 | if (pending == 0) { | ||
179 | pp->imr &= ~ALTERA_JTAGUART_CONTROL_WE_MSK; | ||
180 | writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG); | ||
181 | } | ||
182 | } | ||
183 | |||
184 | static irqreturn_t altera_jtaguart_interrupt(int irq, void *data) | ||
185 | { | ||
186 | struct uart_port *port = data; | ||
187 | struct altera_jtaguart *pp = | ||
188 | container_of(port, struct altera_jtaguart, port); | ||
189 | unsigned int isr; | ||
190 | |||
191 | isr = (readl(port->membase + ALTERA_JTAGUART_CONTROL_REG) >> | ||
192 | ALTERA_JTAGUART_CONTROL_RI_OFF) & pp->imr; | ||
193 | |||
194 | spin_lock(&port->lock); | ||
195 | |||
196 | if (isr & ALTERA_JTAGUART_CONTROL_RE_MSK) | ||
197 | altera_jtaguart_rx_chars(pp); | ||
198 | if (isr & ALTERA_JTAGUART_CONTROL_WE_MSK) | ||
199 | altera_jtaguart_tx_chars(pp); | ||
200 | |||
201 | spin_unlock(&port->lock); | ||
202 | |||
203 | return IRQ_RETVAL(isr); | ||
204 | } | ||
205 | |||
206 | static void altera_jtaguart_config_port(struct uart_port *port, int flags) | ||
207 | { | ||
208 | port->type = PORT_ALTERA_JTAGUART; | ||
209 | |||
210 | /* Clear mask, so no surprise interrupts. */ | ||
211 | writel(0, port->membase + ALTERA_JTAGUART_CONTROL_REG); | ||
212 | } | ||
213 | |||
214 | static int altera_jtaguart_startup(struct uart_port *port) | ||
215 | { | ||
216 | struct altera_jtaguart *pp = | ||
217 | container_of(port, struct altera_jtaguart, port); | ||
218 | unsigned long flags; | ||
219 | int ret; | ||
220 | |||
221 | ret = request_irq(port->irq, altera_jtaguart_interrupt, IRQF_DISABLED, | ||
222 | DRV_NAME, port); | ||
223 | if (ret) { | ||
224 | pr_err(DRV_NAME ": unable to attach Altera JTAG UART %d " | ||
225 | "interrupt vector=%d\n", port->line, port->irq); | ||
226 | return ret; | ||
227 | } | ||
228 | |||
229 | spin_lock_irqsave(&port->lock, flags); | ||
230 | |||
231 | /* Enable RX interrupts now */ | ||
232 | pp->imr = ALTERA_JTAGUART_CONTROL_RE_MSK; | ||
233 | writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG); | ||
234 | |||
235 | spin_unlock_irqrestore(&port->lock, flags); | ||
236 | |||
237 | return 0; | ||
238 | } | ||
239 | |||
240 | static void altera_jtaguart_shutdown(struct uart_port *port) | ||
241 | { | ||
242 | struct altera_jtaguart *pp = | ||
243 | container_of(port, struct altera_jtaguart, port); | ||
244 | unsigned long flags; | ||
245 | |||
246 | spin_lock_irqsave(&port->lock, flags); | ||
247 | |||
248 | /* Disable all interrupts now */ | ||
249 | pp->imr = 0; | ||
250 | writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG); | ||
251 | |||
252 | spin_unlock_irqrestore(&port->lock, flags); | ||
253 | |||
254 | free_irq(port->irq, port); | ||
255 | } | ||
256 | |||
257 | static const char *altera_jtaguart_type(struct uart_port *port) | ||
258 | { | ||
259 | return (port->type == PORT_ALTERA_JTAGUART) ? "Altera JTAG UART" : NULL; | ||
260 | } | ||
261 | |||
262 | static int altera_jtaguart_request_port(struct uart_port *port) | ||
263 | { | ||
264 | /* UARTs always present */ | ||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | static void altera_jtaguart_release_port(struct uart_port *port) | ||
269 | { | ||
270 | /* Nothing to release... */ | ||
271 | } | ||
272 | |||
273 | static int altera_jtaguart_verify_port(struct uart_port *port, | ||
274 | struct serial_struct *ser) | ||
275 | { | ||
276 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_ALTERA_JTAGUART) | ||
277 | return -EINVAL; | ||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | /* | ||
282 | * Define the basic serial functions we support. | ||
283 | */ | ||
284 | static struct uart_ops altera_jtaguart_ops = { | ||
285 | .tx_empty = altera_jtaguart_tx_empty, | ||
286 | .get_mctrl = altera_jtaguart_get_mctrl, | ||
287 | .set_mctrl = altera_jtaguart_set_mctrl, | ||
288 | .start_tx = altera_jtaguart_start_tx, | ||
289 | .stop_tx = altera_jtaguart_stop_tx, | ||
290 | .stop_rx = altera_jtaguart_stop_rx, | ||
291 | .enable_ms = altera_jtaguart_enable_ms, | ||
292 | .break_ctl = altera_jtaguart_break_ctl, | ||
293 | .startup = altera_jtaguart_startup, | ||
294 | .shutdown = altera_jtaguart_shutdown, | ||
295 | .set_termios = altera_jtaguart_set_termios, | ||
296 | .type = altera_jtaguart_type, | ||
297 | .request_port = altera_jtaguart_request_port, | ||
298 | .release_port = altera_jtaguart_release_port, | ||
299 | .config_port = altera_jtaguart_config_port, | ||
300 | .verify_port = altera_jtaguart_verify_port, | ||
301 | }; | ||
302 | |||
303 | #define ALTERA_JTAGUART_MAXPORTS 1 | ||
304 | static struct altera_jtaguart altera_jtaguart_ports[ALTERA_JTAGUART_MAXPORTS]; | ||
305 | |||
306 | #if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE) | ||
307 | |||
308 | int __init early_altera_jtaguart_setup(struct altera_jtaguart_platform_uart | ||
309 | *platp) | ||
310 | { | ||
311 | struct uart_port *port; | ||
312 | int i; | ||
313 | |||
314 | for (i = 0; i < ALTERA_JTAGUART_MAXPORTS && platp[i].mapbase; i++) { | ||
315 | port = &altera_jtaguart_ports[i].port; | ||
316 | |||
317 | port->line = i; | ||
318 | port->type = PORT_ALTERA_JTAGUART; | ||
319 | port->mapbase = platp[i].mapbase; | ||
320 | port->membase = ioremap(port->mapbase, ALTERA_JTAGUART_SIZE); | ||
321 | port->iotype = SERIAL_IO_MEM; | ||
322 | port->irq = platp[i].irq; | ||
323 | port->flags = ASYNC_BOOT_AUTOCONF; | ||
324 | port->ops = &altera_jtaguart_ops; | ||
325 | } | ||
326 | |||
327 | return 0; | ||
328 | } | ||
329 | |||
330 | #if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS) | ||
331 | static void altera_jtaguart_console_putc(struct console *co, const char c) | ||
332 | { | ||
333 | struct uart_port *port = &(altera_jtaguart_ports + co->index)->port; | ||
334 | unsigned long status; | ||
335 | unsigned long flags; | ||
336 | |||
337 | spin_lock_irqsave(&port->lock, flags); | ||
338 | while (((status = readl(port->membase + ALTERA_JTAGUART_CONTROL_REG)) & | ||
339 | ALTERA_JTAGUART_CONTROL_WSPACE_MSK) == 0) { | ||
340 | if ((status & ALTERA_JTAGUART_CONTROL_AC_MSK) == 0) { | ||
341 | spin_unlock_irqrestore(&port->lock, flags); | ||
342 | return; /* no connection activity */ | ||
343 | } | ||
344 | spin_unlock_irqrestore(&port->lock, flags); | ||
345 | cpu_relax(); | ||
346 | spin_lock_irqsave(&port->lock, flags); | ||
347 | } | ||
348 | writel(c, port->membase + ALTERA_JTAGUART_DATA_REG); | ||
349 | spin_unlock_irqrestore(&port->lock, flags); | ||
350 | } | ||
351 | #else | ||
352 | static void altera_jtaguart_console_putc(struct console *co, const char c) | ||
353 | { | ||
354 | struct uart_port *port = &(altera_jtaguart_ports + co->index)->port; | ||
355 | unsigned long flags; | ||
356 | |||
357 | spin_lock_irqsave(&port->lock, flags); | ||
358 | while ((readl(port->membase + ALTERA_JTAGUART_CONTROL_REG) & | ||
359 | ALTERA_JTAGUART_CONTROL_WSPACE_MSK) == 0) { | ||
360 | spin_unlock_irqrestore(&port->lock, flags); | ||
361 | cpu_relax(); | ||
362 | spin_lock_irqsave(&port->lock, flags); | ||
363 | } | ||
364 | writel(c, port->membase + ALTERA_JTAGUART_DATA_REG); | ||
365 | spin_unlock_irqrestore(&port->lock, flags); | ||
366 | } | ||
367 | #endif | ||
368 | |||
369 | static void altera_jtaguart_console_write(struct console *co, const char *s, | ||
370 | unsigned int count) | ||
371 | { | ||
372 | for (; count; count--, s++) { | ||
373 | altera_jtaguart_console_putc(co, *s); | ||
374 | if (*s == '\n') | ||
375 | altera_jtaguart_console_putc(co, '\r'); | ||
376 | } | ||
377 | } | ||
378 | |||
379 | static int __init altera_jtaguart_console_setup(struct console *co, | ||
380 | char *options) | ||
381 | { | ||
382 | struct uart_port *port; | ||
383 | |||
384 | if (co->index < 0 || co->index >= ALTERA_JTAGUART_MAXPORTS) | ||
385 | return -EINVAL; | ||
386 | port = &altera_jtaguart_ports[co->index].port; | ||
387 | if (port->membase == 0) | ||
388 | return -ENODEV; | ||
389 | return 0; | ||
390 | } | ||
391 | |||
392 | static struct uart_driver altera_jtaguart_driver; | ||
393 | |||
394 | static struct console altera_jtaguart_console = { | ||
395 | .name = "ttyJ", | ||
396 | .write = altera_jtaguart_console_write, | ||
397 | .device = uart_console_device, | ||
398 | .setup = altera_jtaguart_console_setup, | ||
399 | .flags = CON_PRINTBUFFER, | ||
400 | .index = -1, | ||
401 | .data = &altera_jtaguart_driver, | ||
402 | }; | ||
403 | |||
404 | static int __init altera_jtaguart_console_init(void) | ||
405 | { | ||
406 | register_console(&altera_jtaguart_console); | ||
407 | return 0; | ||
408 | } | ||
409 | |||
410 | console_initcall(altera_jtaguart_console_init); | ||
411 | |||
412 | #define ALTERA_JTAGUART_CONSOLE (&altera_jtaguart_console) | ||
413 | |||
414 | #else | ||
415 | |||
416 | #define ALTERA_JTAGUART_CONSOLE NULL | ||
417 | |||
418 | #endif /* CONFIG_ALTERA_JTAGUART_CONSOLE */ | ||
419 | |||
420 | static struct uart_driver altera_jtaguart_driver = { | ||
421 | .owner = THIS_MODULE, | ||
422 | .driver_name = "altera_jtaguart", | ||
423 | .dev_name = "ttyJ", | ||
424 | .major = ALTERA_JTAGUART_MAJOR, | ||
425 | .minor = ALTERA_JTAGUART_MINOR, | ||
426 | .nr = ALTERA_JTAGUART_MAXPORTS, | ||
427 | .cons = ALTERA_JTAGUART_CONSOLE, | ||
428 | }; | ||
429 | |||
430 | static int __devinit altera_jtaguart_probe(struct platform_device *pdev) | ||
431 | { | ||
432 | struct altera_jtaguart_platform_uart *platp = pdev->dev.platform_data; | ||
433 | struct uart_port *port; | ||
434 | int i; | ||
435 | |||
436 | for (i = 0; i < ALTERA_JTAGUART_MAXPORTS && platp[i].mapbase; i++) { | ||
437 | port = &altera_jtaguart_ports[i].port; | ||
438 | |||
439 | port->line = i; | ||
440 | port->type = PORT_ALTERA_JTAGUART; | ||
441 | port->mapbase = platp[i].mapbase; | ||
442 | port->membase = ioremap(port->mapbase, ALTERA_JTAGUART_SIZE); | ||
443 | port->iotype = SERIAL_IO_MEM; | ||
444 | port->irq = platp[i].irq; | ||
445 | port->ops = &altera_jtaguart_ops; | ||
446 | port->flags = ASYNC_BOOT_AUTOCONF; | ||
447 | |||
448 | uart_add_one_port(&altera_jtaguart_driver, port); | ||
449 | } | ||
450 | |||
451 | return 0; | ||
452 | } | ||
453 | |||
454 | static int __devexit altera_jtaguart_remove(struct platform_device *pdev) | ||
455 | { | ||
456 | struct uart_port *port; | ||
457 | int i; | ||
458 | |||
459 | for (i = 0; i < ALTERA_JTAGUART_MAXPORTS; i++) { | ||
460 | port = &altera_jtaguart_ports[i].port; | ||
461 | if (port) | ||
462 | uart_remove_one_port(&altera_jtaguart_driver, port); | ||
463 | } | ||
464 | |||
465 | return 0; | ||
466 | } | ||
467 | |||
468 | static struct platform_driver altera_jtaguart_platform_driver = { | ||
469 | .probe = altera_jtaguart_probe, | ||
470 | .remove = __devexit_p(altera_jtaguart_remove), | ||
471 | .driver = { | ||
472 | .name = DRV_NAME, | ||
473 | .owner = THIS_MODULE, | ||
474 | }, | ||
475 | }; | ||
476 | |||
477 | static int __init altera_jtaguart_init(void) | ||
478 | { | ||
479 | int rc; | ||
480 | |||
481 | rc = uart_register_driver(&altera_jtaguart_driver); | ||
482 | if (rc) | ||
483 | return rc; | ||
484 | rc = platform_driver_register(&altera_jtaguart_platform_driver); | ||
485 | if (rc) { | ||
486 | uart_unregister_driver(&altera_jtaguart_driver); | ||
487 | return rc; | ||
488 | } | ||
489 | return 0; | ||
490 | } | ||
491 | |||
492 | static void __exit altera_jtaguart_exit(void) | ||
493 | { | ||
494 | platform_driver_unregister(&altera_jtaguart_platform_driver); | ||
495 | uart_unregister_driver(&altera_jtaguart_driver); | ||
496 | } | ||
497 | |||
498 | module_init(altera_jtaguart_init); | ||
499 | module_exit(altera_jtaguart_exit); | ||
500 | |||
501 | MODULE_DESCRIPTION("Altera JTAG UART driver"); | ||
502 | MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>"); | ||
503 | MODULE_LICENSE("GPL"); | ||
504 | MODULE_ALIAS("platform:" DRV_NAME); | ||
diff --git a/drivers/serial/altera_uart.c b/drivers/serial/altera_uart.c new file mode 100644 index 000000000000..721216292a50 --- /dev/null +++ b/drivers/serial/altera_uart.c | |||
@@ -0,0 +1,608 @@ | |||
1 | /* | ||
2 | * altera_uart.c -- Altera UART driver | ||
3 | * | ||
4 | * Based on mcf.c -- Freescale ColdFire UART driver | ||
5 | * | ||
6 | * (C) Copyright 2003-2007, Greg Ungerer <gerg@snapgear.com> | ||
7 | * (C) Copyright 2008, Thomas Chou <thomas@wytron.com.tw> | ||
8 | * (C) Copyright 2010, Tobias Klauser <tklauser@distanz.ch> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/timer.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/console.h> | ||
22 | #include <linux/tty.h> | ||
23 | #include <linux/tty_flip.h> | ||
24 | #include <linux/serial.h> | ||
25 | #include <linux/serial_core.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/io.h> | ||
28 | #include <linux/altera_uart.h> | ||
29 | |||
30 | #define DRV_NAME "altera_uart" | ||
31 | #define SERIAL_ALTERA_MAJOR 204 | ||
32 | #define SERIAL_ALTERA_MINOR 213 | ||
33 | |||
34 | /* | ||
35 | * Altera UART register definitions according to the Nios UART datasheet: | ||
36 | * http://www.altera.com/literature/ds/ds_nios_uart.pdf | ||
37 | */ | ||
38 | |||
39 | #define ALTERA_UART_SIZE 32 | ||
40 | |||
41 | #define ALTERA_UART_RXDATA_REG 0 | ||
42 | #define ALTERA_UART_TXDATA_REG 4 | ||
43 | #define ALTERA_UART_STATUS_REG 8 | ||
44 | #define ALTERA_UART_CONTROL_REG 12 | ||
45 | #define ALTERA_UART_DIVISOR_REG 16 | ||
46 | #define ALTERA_UART_EOP_REG 20 | ||
47 | |||
48 | #define ALTERA_UART_STATUS_PE_MSK 0x0001 /* parity error */ | ||
49 | #define ALTERA_UART_STATUS_FE_MSK 0x0002 /* framing error */ | ||
50 | #define ALTERA_UART_STATUS_BRK_MSK 0x0004 /* break */ | ||
51 | #define ALTERA_UART_STATUS_ROE_MSK 0x0008 /* RX overrun error */ | ||
52 | #define ALTERA_UART_STATUS_TOE_MSK 0x0010 /* TX overrun error */ | ||
53 | #define ALTERA_UART_STATUS_TMT_MSK 0x0020 /* TX shift register state */ | ||
54 | #define ALTERA_UART_STATUS_TRDY_MSK 0x0040 /* TX ready */ | ||
55 | #define ALTERA_UART_STATUS_RRDY_MSK 0x0080 /* RX ready */ | ||
56 | #define ALTERA_UART_STATUS_E_MSK 0x0100 /* exception condition */ | ||
57 | #define ALTERA_UART_STATUS_DCTS_MSK 0x0400 /* CTS logic-level change */ | ||
58 | #define ALTERA_UART_STATUS_CTS_MSK 0x0800 /* CTS logic state */ | ||
59 | #define ALTERA_UART_STATUS_EOP_MSK 0x1000 /* EOP written/read */ | ||
60 | |||
61 | /* Enable interrupt on... */ | ||
62 | #define ALTERA_UART_CONTROL_PE_MSK 0x0001 /* ...parity error */ | ||
63 | #define ALTERA_UART_CONTROL_FE_MSK 0x0002 /* ...framing error */ | ||
64 | #define ALTERA_UART_CONTROL_BRK_MSK 0x0004 /* ...break */ | ||
65 | #define ALTERA_UART_CONTROL_ROE_MSK 0x0008 /* ...RX overrun */ | ||
66 | #define ALTERA_UART_CONTROL_TOE_MSK 0x0010 /* ...TX overrun */ | ||
67 | #define ALTERA_UART_CONTROL_TMT_MSK 0x0020 /* ...TX shift register empty */ | ||
68 | #define ALTERA_UART_CONTROL_TRDY_MSK 0x0040 /* ...TX ready */ | ||
69 | #define ALTERA_UART_CONTROL_RRDY_MSK 0x0080 /* ...RX ready */ | ||
70 | #define ALTERA_UART_CONTROL_E_MSK 0x0100 /* ...exception*/ | ||
71 | |||
72 | #define ALTERA_UART_CONTROL_TRBK_MSK 0x0200 /* TX break */ | ||
73 | #define ALTERA_UART_CONTROL_DCTS_MSK 0x0400 /* Interrupt on CTS change */ | ||
74 | #define ALTERA_UART_CONTROL_RTS_MSK 0x0800 /* RTS signal */ | ||
75 | #define ALTERA_UART_CONTROL_EOP_MSK 0x1000 /* Interrupt on EOP */ | ||
76 | |||
77 | /* | ||
78 | * Local per-uart structure. | ||
79 | */ | ||
80 | struct altera_uart { | ||
81 | struct uart_port port; | ||
82 | struct timer_list tmr; | ||
83 | unsigned int sigs; /* Local copy of line sigs */ | ||
84 | unsigned short imr; /* Local IMR mirror */ | ||
85 | }; | ||
86 | |||
87 | static u32 altera_uart_readl(struct uart_port *port, int reg) | ||
88 | { | ||
89 | struct altera_uart_platform_uart *platp = port->private_data; | ||
90 | |||
91 | return readl(port->membase + (reg << platp->bus_shift)); | ||
92 | } | ||
93 | |||
94 | static void altera_uart_writel(struct uart_port *port, u32 dat, int reg) | ||
95 | { | ||
96 | struct altera_uart_platform_uart *platp = port->private_data; | ||
97 | |||
98 | writel(dat, port->membase + (reg << platp->bus_shift)); | ||
99 | } | ||
100 | |||
101 | static unsigned int altera_uart_tx_empty(struct uart_port *port) | ||
102 | { | ||
103 | return (altera_uart_readl(port, ALTERA_UART_STATUS_REG) & | ||
104 | ALTERA_UART_STATUS_TMT_MSK) ? TIOCSER_TEMT : 0; | ||
105 | } | ||
106 | |||
107 | static unsigned int altera_uart_get_mctrl(struct uart_port *port) | ||
108 | { | ||
109 | struct altera_uart *pp = container_of(port, struct altera_uart, port); | ||
110 | unsigned int sigs; | ||
111 | |||
112 | sigs = (altera_uart_readl(port, ALTERA_UART_STATUS_REG) & | ||
113 | ALTERA_UART_STATUS_CTS_MSK) ? TIOCM_CTS : 0; | ||
114 | sigs |= (pp->sigs & TIOCM_RTS); | ||
115 | |||
116 | return sigs; | ||
117 | } | ||
118 | |||
119 | static void altera_uart_set_mctrl(struct uart_port *port, unsigned int sigs) | ||
120 | { | ||
121 | struct altera_uart *pp = container_of(port, struct altera_uart, port); | ||
122 | |||
123 | pp->sigs = sigs; | ||
124 | if (sigs & TIOCM_RTS) | ||
125 | pp->imr |= ALTERA_UART_CONTROL_RTS_MSK; | ||
126 | else | ||
127 | pp->imr &= ~ALTERA_UART_CONTROL_RTS_MSK; | ||
128 | altera_uart_writel(port, pp->imr, ALTERA_UART_CONTROL_REG); | ||
129 | } | ||
130 | |||
131 | static void altera_uart_start_tx(struct uart_port *port) | ||
132 | { | ||
133 | struct altera_uart *pp = container_of(port, struct altera_uart, port); | ||
134 | |||
135 | pp->imr |= ALTERA_UART_CONTROL_TRDY_MSK; | ||
136 | altera_uart_writel(port, pp->imr, ALTERA_UART_CONTROL_REG); | ||
137 | } | ||
138 | |||
139 | static void altera_uart_stop_tx(struct uart_port *port) | ||
140 | { | ||
141 | struct altera_uart *pp = container_of(port, struct altera_uart, port); | ||
142 | |||
143 | pp->imr &= ~ALTERA_UART_CONTROL_TRDY_MSK; | ||
144 | altera_uart_writel(port, pp->imr, ALTERA_UART_CONTROL_REG); | ||
145 | } | ||
146 | |||
147 | static void altera_uart_stop_rx(struct uart_port *port) | ||
148 | { | ||
149 | struct altera_uart *pp = container_of(port, struct altera_uart, port); | ||
150 | |||
151 | pp->imr &= ~ALTERA_UART_CONTROL_RRDY_MSK; | ||
152 | altera_uart_writel(port, pp->imr, ALTERA_UART_CONTROL_REG); | ||
153 | } | ||
154 | |||
155 | static void altera_uart_break_ctl(struct uart_port *port, int break_state) | ||
156 | { | ||
157 | struct altera_uart *pp = container_of(port, struct altera_uart, port); | ||
158 | unsigned long flags; | ||
159 | |||
160 | spin_lock_irqsave(&port->lock, flags); | ||
161 | if (break_state == -1) | ||
162 | pp->imr |= ALTERA_UART_CONTROL_TRBK_MSK; | ||
163 | else | ||
164 | pp->imr &= ~ALTERA_UART_CONTROL_TRBK_MSK; | ||
165 | altera_uart_writel(port, pp->imr, ALTERA_UART_CONTROL_REG); | ||
166 | spin_unlock_irqrestore(&port->lock, flags); | ||
167 | } | ||
168 | |||
169 | static void altera_uart_enable_ms(struct uart_port *port) | ||
170 | { | ||
171 | } | ||
172 | |||
173 | static void altera_uart_set_termios(struct uart_port *port, | ||
174 | struct ktermios *termios, | ||
175 | struct ktermios *old) | ||
176 | { | ||
177 | unsigned long flags; | ||
178 | unsigned int baud, baudclk; | ||
179 | |||
180 | baud = uart_get_baud_rate(port, termios, old, 0, 4000000); | ||
181 | baudclk = port->uartclk / baud; | ||
182 | |||
183 | if (old) | ||
184 | tty_termios_copy_hw(termios, old); | ||
185 | tty_termios_encode_baud_rate(termios, baud, baud); | ||
186 | |||
187 | spin_lock_irqsave(&port->lock, flags); | ||
188 | uart_update_timeout(port, termios->c_cflag, baud); | ||
189 | altera_uart_writel(port, baudclk, ALTERA_UART_DIVISOR_REG); | ||
190 | spin_unlock_irqrestore(&port->lock, flags); | ||
191 | } | ||
192 | |||
193 | static void altera_uart_rx_chars(struct altera_uart *pp) | ||
194 | { | ||
195 | struct uart_port *port = &pp->port; | ||
196 | unsigned char ch, flag; | ||
197 | unsigned short status; | ||
198 | |||
199 | while ((status = altera_uart_readl(port, ALTERA_UART_STATUS_REG)) & | ||
200 | ALTERA_UART_STATUS_RRDY_MSK) { | ||
201 | ch = altera_uart_readl(port, ALTERA_UART_RXDATA_REG); | ||
202 | flag = TTY_NORMAL; | ||
203 | port->icount.rx++; | ||
204 | |||
205 | if (status & ALTERA_UART_STATUS_E_MSK) { | ||
206 | altera_uart_writel(port, status, | ||
207 | ALTERA_UART_STATUS_REG); | ||
208 | |||
209 | if (status & ALTERA_UART_STATUS_BRK_MSK) { | ||
210 | port->icount.brk++; | ||
211 | if (uart_handle_break(port)) | ||
212 | continue; | ||
213 | } else if (status & ALTERA_UART_STATUS_PE_MSK) { | ||
214 | port->icount.parity++; | ||
215 | } else if (status & ALTERA_UART_STATUS_ROE_MSK) { | ||
216 | port->icount.overrun++; | ||
217 | } else if (status & ALTERA_UART_STATUS_FE_MSK) { | ||
218 | port->icount.frame++; | ||
219 | } | ||
220 | |||
221 | status &= port->read_status_mask; | ||
222 | |||
223 | if (status & ALTERA_UART_STATUS_BRK_MSK) | ||
224 | flag = TTY_BREAK; | ||
225 | else if (status & ALTERA_UART_STATUS_PE_MSK) | ||
226 | flag = TTY_PARITY; | ||
227 | else if (status & ALTERA_UART_STATUS_FE_MSK) | ||
228 | flag = TTY_FRAME; | ||
229 | } | ||
230 | |||
231 | if (uart_handle_sysrq_char(port, ch)) | ||
232 | continue; | ||
233 | uart_insert_char(port, status, ALTERA_UART_STATUS_ROE_MSK, ch, | ||
234 | flag); | ||
235 | } | ||
236 | |||
237 | tty_flip_buffer_push(port->state->port.tty); | ||
238 | } | ||
239 | |||
240 | static void altera_uart_tx_chars(struct altera_uart *pp) | ||
241 | { | ||
242 | struct uart_port *port = &pp->port; | ||
243 | struct circ_buf *xmit = &port->state->xmit; | ||
244 | |||
245 | if (port->x_char) { | ||
246 | /* Send special char - probably flow control */ | ||
247 | altera_uart_writel(port, port->x_char, ALTERA_UART_TXDATA_REG); | ||
248 | port->x_char = 0; | ||
249 | port->icount.tx++; | ||
250 | return; | ||
251 | } | ||
252 | |||
253 | while (altera_uart_readl(port, ALTERA_UART_STATUS_REG) & | ||
254 | ALTERA_UART_STATUS_TRDY_MSK) { | ||
255 | if (xmit->head == xmit->tail) | ||
256 | break; | ||
257 | altera_uart_writel(port, xmit->buf[xmit->tail], | ||
258 | ALTERA_UART_TXDATA_REG); | ||
259 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
260 | port->icount.tx++; | ||
261 | } | ||
262 | |||
263 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
264 | uart_write_wakeup(port); | ||
265 | |||
266 | if (xmit->head == xmit->tail) { | ||
267 | pp->imr &= ~ALTERA_UART_CONTROL_TRDY_MSK; | ||
268 | altera_uart_writel(port, pp->imr, ALTERA_UART_CONTROL_REG); | ||
269 | } | ||
270 | } | ||
271 | |||
272 | static irqreturn_t altera_uart_interrupt(int irq, void *data) | ||
273 | { | ||
274 | struct uart_port *port = data; | ||
275 | struct altera_uart *pp = container_of(port, struct altera_uart, port); | ||
276 | unsigned int isr; | ||
277 | |||
278 | isr = altera_uart_readl(port, ALTERA_UART_STATUS_REG) & pp->imr; | ||
279 | |||
280 | spin_lock(&port->lock); | ||
281 | if (isr & ALTERA_UART_STATUS_RRDY_MSK) | ||
282 | altera_uart_rx_chars(pp); | ||
283 | if (isr & ALTERA_UART_STATUS_TRDY_MSK) | ||
284 | altera_uart_tx_chars(pp); | ||
285 | spin_unlock(&port->lock); | ||
286 | |||
287 | return IRQ_RETVAL(isr); | ||
288 | } | ||
289 | |||
290 | static void altera_uart_timer(unsigned long data) | ||
291 | { | ||
292 | struct uart_port *port = (void *)data; | ||
293 | struct altera_uart *pp = container_of(port, struct altera_uart, port); | ||
294 | |||
295 | altera_uart_interrupt(0, port); | ||
296 | mod_timer(&pp->tmr, jiffies + uart_poll_timeout(port)); | ||
297 | } | ||
298 | |||
299 | static void altera_uart_config_port(struct uart_port *port, int flags) | ||
300 | { | ||
301 | port->type = PORT_ALTERA_UART; | ||
302 | |||
303 | /* Clear mask, so no surprise interrupts. */ | ||
304 | altera_uart_writel(port, 0, ALTERA_UART_CONTROL_REG); | ||
305 | /* Clear status register */ | ||
306 | altera_uart_writel(port, 0, ALTERA_UART_STATUS_REG); | ||
307 | } | ||
308 | |||
309 | static int altera_uart_startup(struct uart_port *port) | ||
310 | { | ||
311 | struct altera_uart *pp = container_of(port, struct altera_uart, port); | ||
312 | unsigned long flags; | ||
313 | int ret; | ||
314 | |||
315 | if (!port->irq) { | ||
316 | setup_timer(&pp->tmr, altera_uart_timer, (unsigned long)port); | ||
317 | mod_timer(&pp->tmr, jiffies + uart_poll_timeout(port)); | ||
318 | return 0; | ||
319 | } | ||
320 | |||
321 | ret = request_irq(port->irq, altera_uart_interrupt, IRQF_DISABLED, | ||
322 | DRV_NAME, port); | ||
323 | if (ret) { | ||
324 | pr_err(DRV_NAME ": unable to attach Altera UART %d " | ||
325 | "interrupt vector=%d\n", port->line, port->irq); | ||
326 | return ret; | ||
327 | } | ||
328 | |||
329 | spin_lock_irqsave(&port->lock, flags); | ||
330 | |||
331 | /* Enable RX interrupts now */ | ||
332 | pp->imr = ALTERA_UART_CONTROL_RRDY_MSK; | ||
333 | writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); | ||
334 | |||
335 | spin_unlock_irqrestore(&port->lock, flags); | ||
336 | |||
337 | return 0; | ||
338 | } | ||
339 | |||
340 | static void altera_uart_shutdown(struct uart_port *port) | ||
341 | { | ||
342 | struct altera_uart *pp = container_of(port, struct altera_uart, port); | ||
343 | unsigned long flags; | ||
344 | |||
345 | spin_lock_irqsave(&port->lock, flags); | ||
346 | |||
347 | /* Disable all interrupts now */ | ||
348 | pp->imr = 0; | ||
349 | writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); | ||
350 | |||
351 | spin_unlock_irqrestore(&port->lock, flags); | ||
352 | |||
353 | if (port->irq) | ||
354 | free_irq(port->irq, port); | ||
355 | else | ||
356 | del_timer_sync(&pp->tmr); | ||
357 | } | ||
358 | |||
359 | static const char *altera_uart_type(struct uart_port *port) | ||
360 | { | ||
361 | return (port->type == PORT_ALTERA_UART) ? "Altera UART" : NULL; | ||
362 | } | ||
363 | |||
364 | static int altera_uart_request_port(struct uart_port *port) | ||
365 | { | ||
366 | /* UARTs always present */ | ||
367 | return 0; | ||
368 | } | ||
369 | |||
370 | static void altera_uart_release_port(struct uart_port *port) | ||
371 | { | ||
372 | /* Nothing to release... */ | ||
373 | } | ||
374 | |||
375 | static int altera_uart_verify_port(struct uart_port *port, | ||
376 | struct serial_struct *ser) | ||
377 | { | ||
378 | if ((ser->type != PORT_UNKNOWN) && (ser->type != PORT_ALTERA_UART)) | ||
379 | return -EINVAL; | ||
380 | return 0; | ||
381 | } | ||
382 | |||
383 | /* | ||
384 | * Define the basic serial functions we support. | ||
385 | */ | ||
386 | static struct uart_ops altera_uart_ops = { | ||
387 | .tx_empty = altera_uart_tx_empty, | ||
388 | .get_mctrl = altera_uart_get_mctrl, | ||
389 | .set_mctrl = altera_uart_set_mctrl, | ||
390 | .start_tx = altera_uart_start_tx, | ||
391 | .stop_tx = altera_uart_stop_tx, | ||
392 | .stop_rx = altera_uart_stop_rx, | ||
393 | .enable_ms = altera_uart_enable_ms, | ||
394 | .break_ctl = altera_uart_break_ctl, | ||
395 | .startup = altera_uart_startup, | ||
396 | .shutdown = altera_uart_shutdown, | ||
397 | .set_termios = altera_uart_set_termios, | ||
398 | .type = altera_uart_type, | ||
399 | .request_port = altera_uart_request_port, | ||
400 | .release_port = altera_uart_release_port, | ||
401 | .config_port = altera_uart_config_port, | ||
402 | .verify_port = altera_uart_verify_port, | ||
403 | }; | ||
404 | |||
405 | static struct altera_uart altera_uart_ports[CONFIG_SERIAL_ALTERA_UART_MAXPORTS]; | ||
406 | |||
407 | #if defined(CONFIG_SERIAL_ALTERA_UART_CONSOLE) | ||
408 | |||
409 | int __init early_altera_uart_setup(struct altera_uart_platform_uart *platp) | ||
410 | { | ||
411 | struct uart_port *port; | ||
412 | int i; | ||
413 | |||
414 | for (i = 0; i < CONFIG_SERIAL_ALTERA_UART_MAXPORTS && platp[i].mapbase; i++) { | ||
415 | port = &altera_uart_ports[i].port; | ||
416 | |||
417 | port->line = i; | ||
418 | port->type = PORT_ALTERA_UART; | ||
419 | port->mapbase = platp[i].mapbase; | ||
420 | port->membase = ioremap(port->mapbase, ALTERA_UART_SIZE); | ||
421 | port->iotype = SERIAL_IO_MEM; | ||
422 | port->irq = platp[i].irq; | ||
423 | port->uartclk = platp[i].uartclk; | ||
424 | port->flags = UPF_BOOT_AUTOCONF; | ||
425 | port->ops = &altera_uart_ops; | ||
426 | port->private_data = platp; | ||
427 | } | ||
428 | |||
429 | return 0; | ||
430 | } | ||
431 | |||
432 | static void altera_uart_console_putc(struct uart_port *port, const char c) | ||
433 | { | ||
434 | while (!(altera_uart_readl(port, ALTERA_UART_STATUS_REG) & | ||
435 | ALTERA_UART_STATUS_TRDY_MSK)) | ||
436 | cpu_relax(); | ||
437 | |||
438 | writel(c, port->membase + ALTERA_UART_TXDATA_REG); | ||
439 | } | ||
440 | |||
441 | static void altera_uart_console_write(struct console *co, const char *s, | ||
442 | unsigned int count) | ||
443 | { | ||
444 | struct uart_port *port = &(altera_uart_ports + co->index)->port; | ||
445 | |||
446 | for (; count; count--, s++) { | ||
447 | altera_uart_console_putc(port, *s); | ||
448 | if (*s == '\n') | ||
449 | altera_uart_console_putc(port, '\r'); | ||
450 | } | ||
451 | } | ||
452 | |||
453 | static int __init altera_uart_console_setup(struct console *co, char *options) | ||
454 | { | ||
455 | struct uart_port *port; | ||
456 | int baud = CONFIG_SERIAL_ALTERA_UART_BAUDRATE; | ||
457 | int bits = 8; | ||
458 | int parity = 'n'; | ||
459 | int flow = 'n'; | ||
460 | |||
461 | if (co->index < 0 || co->index >= CONFIG_SERIAL_ALTERA_UART_MAXPORTS) | ||
462 | return -EINVAL; | ||
463 | port = &altera_uart_ports[co->index].port; | ||
464 | if (!port->membase) | ||
465 | return -ENODEV; | ||
466 | |||
467 | if (options) | ||
468 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
469 | |||
470 | return uart_set_options(port, co, baud, parity, bits, flow); | ||
471 | } | ||
472 | |||
473 | static struct uart_driver altera_uart_driver; | ||
474 | |||
475 | static struct console altera_uart_console = { | ||
476 | .name = "ttyAL", | ||
477 | .write = altera_uart_console_write, | ||
478 | .device = uart_console_device, | ||
479 | .setup = altera_uart_console_setup, | ||
480 | .flags = CON_PRINTBUFFER, | ||
481 | .index = -1, | ||
482 | .data = &altera_uart_driver, | ||
483 | }; | ||
484 | |||
485 | static int __init altera_uart_console_init(void) | ||
486 | { | ||
487 | register_console(&altera_uart_console); | ||
488 | return 0; | ||
489 | } | ||
490 | |||
491 | console_initcall(altera_uart_console_init); | ||
492 | |||
493 | #define ALTERA_UART_CONSOLE (&altera_uart_console) | ||
494 | |||
495 | #else | ||
496 | |||
497 | #define ALTERA_UART_CONSOLE NULL | ||
498 | |||
499 | #endif /* CONFIG_ALTERA_UART_CONSOLE */ | ||
500 | |||
501 | /* | ||
502 | * Define the altera_uart UART driver structure. | ||
503 | */ | ||
504 | static struct uart_driver altera_uart_driver = { | ||
505 | .owner = THIS_MODULE, | ||
506 | .driver_name = DRV_NAME, | ||
507 | .dev_name = "ttyAL", | ||
508 | .major = SERIAL_ALTERA_MAJOR, | ||
509 | .minor = SERIAL_ALTERA_MINOR, | ||
510 | .nr = CONFIG_SERIAL_ALTERA_UART_MAXPORTS, | ||
511 | .cons = ALTERA_UART_CONSOLE, | ||
512 | }; | ||
513 | |||
514 | static int __devinit altera_uart_probe(struct platform_device *pdev) | ||
515 | { | ||
516 | struct altera_uart_platform_uart *platp = pdev->dev.platform_data; | ||
517 | struct uart_port *port; | ||
518 | struct resource *res_mem; | ||
519 | struct resource *res_irq; | ||
520 | int i = pdev->id; | ||
521 | |||
522 | /* -1 emphasizes that the platform must have one port, no .N suffix */ | ||
523 | if (i == -1) | ||
524 | i = 0; | ||
525 | |||
526 | if (i >= CONFIG_SERIAL_ALTERA_UART_MAXPORTS) | ||
527 | return -EINVAL; | ||
528 | |||
529 | port = &altera_uart_ports[i].port; | ||
530 | |||
531 | res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
532 | if (res_mem) | ||
533 | port->mapbase = res_mem->start; | ||
534 | else if (platp->mapbase) | ||
535 | port->mapbase = platp->mapbase; | ||
536 | else | ||
537 | return -EINVAL; | ||
538 | |||
539 | res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
540 | if (res_irq) | ||
541 | port->irq = res_irq->start; | ||
542 | else if (platp->irq) | ||
543 | port->irq = platp->irq; | ||
544 | |||
545 | port->membase = ioremap(port->mapbase, ALTERA_UART_SIZE); | ||
546 | if (!port->membase) | ||
547 | return -ENOMEM; | ||
548 | |||
549 | port->line = i; | ||
550 | port->type = PORT_ALTERA_UART; | ||
551 | port->iotype = SERIAL_IO_MEM; | ||
552 | port->uartclk = platp->uartclk; | ||
553 | port->ops = &altera_uart_ops; | ||
554 | port->flags = UPF_BOOT_AUTOCONF; | ||
555 | port->private_data = platp; | ||
556 | |||
557 | uart_add_one_port(&altera_uart_driver, port); | ||
558 | |||
559 | return 0; | ||
560 | } | ||
561 | |||
562 | static int __devexit altera_uart_remove(struct platform_device *pdev) | ||
563 | { | ||
564 | struct uart_port *port = &altera_uart_ports[pdev->id].port; | ||
565 | |||
566 | uart_remove_one_port(&altera_uart_driver, port); | ||
567 | return 0; | ||
568 | } | ||
569 | |||
570 | static struct platform_driver altera_uart_platform_driver = { | ||
571 | .probe = altera_uart_probe, | ||
572 | .remove = __devexit_p(altera_uart_remove), | ||
573 | .driver = { | ||
574 | .name = DRV_NAME, | ||
575 | .owner = THIS_MODULE, | ||
576 | .pm = NULL, | ||
577 | }, | ||
578 | }; | ||
579 | |||
580 | static int __init altera_uart_init(void) | ||
581 | { | ||
582 | int rc; | ||
583 | |||
584 | rc = uart_register_driver(&altera_uart_driver); | ||
585 | if (rc) | ||
586 | return rc; | ||
587 | rc = platform_driver_register(&altera_uart_platform_driver); | ||
588 | if (rc) { | ||
589 | uart_unregister_driver(&altera_uart_driver); | ||
590 | return rc; | ||
591 | } | ||
592 | return 0; | ||
593 | } | ||
594 | |||
595 | static void __exit altera_uart_exit(void) | ||
596 | { | ||
597 | platform_driver_unregister(&altera_uart_platform_driver); | ||
598 | uart_unregister_driver(&altera_uart_driver); | ||
599 | } | ||
600 | |||
601 | module_init(altera_uart_init); | ||
602 | module_exit(altera_uart_exit); | ||
603 | |||
604 | MODULE_DESCRIPTION("Altera UART driver"); | ||
605 | MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>"); | ||
606 | MODULE_LICENSE("GPL"); | ||
607 | MODULE_ALIAS("platform:" DRV_NAME); | ||
608 | MODULE_ALIAS_CHARDEV_MAJOR(SERIAL_ALTERA_MAJOR); | ||
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c index 58a4879c7e48..2904aa044126 100644 --- a/drivers/serial/amba-pl010.c +++ b/drivers/serial/amba-pl010.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include <linux/amba/bus.h> | 47 | #include <linux/amba/bus.h> |
48 | #include <linux/amba/serial.h> | 48 | #include <linux/amba/serial.h> |
49 | #include <linux/clk.h> | 49 | #include <linux/clk.h> |
50 | #include <linux/slab.h> | ||
50 | 51 | ||
51 | #include <asm/io.h> | 52 | #include <asm/io.h> |
52 | 53 | ||
@@ -117,7 +118,7 @@ static void pl010_enable_ms(struct uart_port *port) | |||
117 | 118 | ||
118 | static void pl010_rx_chars(struct uart_amba_port *uap) | 119 | static void pl010_rx_chars(struct uart_amba_port *uap) |
119 | { | 120 | { |
120 | struct tty_struct *tty = uap->port.info->port.tty; | 121 | struct tty_struct *tty = uap->port.state->port.tty; |
121 | unsigned int status, ch, flag, rsr, max_count = 256; | 122 | unsigned int status, ch, flag, rsr, max_count = 256; |
122 | 123 | ||
123 | status = readb(uap->port.membase + UART01x_FR); | 124 | status = readb(uap->port.membase + UART01x_FR); |
@@ -172,7 +173,7 @@ static void pl010_rx_chars(struct uart_amba_port *uap) | |||
172 | 173 | ||
173 | static void pl010_tx_chars(struct uart_amba_port *uap) | 174 | static void pl010_tx_chars(struct uart_amba_port *uap) |
174 | { | 175 | { |
175 | struct circ_buf *xmit = &uap->port.info->xmit; | 176 | struct circ_buf *xmit = &uap->port.state->xmit; |
176 | int count; | 177 | int count; |
177 | 178 | ||
178 | if (uap->port.x_char) { | 179 | if (uap->port.x_char) { |
@@ -225,7 +226,7 @@ static void pl010_modem_status(struct uart_amba_port *uap) | |||
225 | if (delta & UART01x_FR_CTS) | 226 | if (delta & UART01x_FR_CTS) |
226 | uart_handle_cts_change(&uap->port, status & UART01x_FR_CTS); | 227 | uart_handle_cts_change(&uap->port, status & UART01x_FR_CTS); |
227 | 228 | ||
228 | wake_up_interruptible(&uap->port.info->delta_msr_wait); | 229 | wake_up_interruptible(&uap->port.state->port.delta_msr_wait); |
229 | } | 230 | } |
230 | 231 | ||
231 | static irqreturn_t pl010_int(int irq, void *dev_id) | 232 | static irqreturn_t pl010_int(int irq, void *dev_id) |
@@ -471,6 +472,15 @@ pl010_set_termios(struct uart_port *port, struct ktermios *termios, | |||
471 | spin_unlock_irqrestore(&uap->port.lock, flags); | 472 | spin_unlock_irqrestore(&uap->port.lock, flags); |
472 | } | 473 | } |
473 | 474 | ||
475 | static void pl010_set_ldisc(struct uart_port *port, int new) | ||
476 | { | ||
477 | if (new == N_PPS) { | ||
478 | port->flags |= UPF_HARDPPS_CD; | ||
479 | pl010_enable_ms(port); | ||
480 | } else | ||
481 | port->flags &= ~UPF_HARDPPS_CD; | ||
482 | } | ||
483 | |||
474 | static const char *pl010_type(struct uart_port *port) | 484 | static const char *pl010_type(struct uart_port *port) |
475 | { | 485 | { |
476 | return port->type == PORT_AMBA ? "AMBA" : NULL; | 486 | return port->type == PORT_AMBA ? "AMBA" : NULL; |
@@ -531,6 +541,7 @@ static struct uart_ops amba_pl010_pops = { | |||
531 | .startup = pl010_startup, | 541 | .startup = pl010_startup, |
532 | .shutdown = pl010_shutdown, | 542 | .shutdown = pl010_shutdown, |
533 | .set_termios = pl010_set_termios, | 543 | .set_termios = pl010_set_termios, |
544 | .set_ldisc = pl010_set_ldisc, | ||
534 | .type = pl010_type, | 545 | .type = pl010_type, |
535 | .release_port = pl010_release_port, | 546 | .release_port = pl010_release_port, |
536 | .request_port = pl010_request_port, | 547 | .request_port = pl010_request_port, |
@@ -766,7 +777,7 @@ static int pl010_resume(struct amba_device *dev) | |||
766 | return 0; | 777 | return 0; |
767 | } | 778 | } |
768 | 779 | ||
769 | static struct amba_id pl010_ids[] __initdata = { | 780 | static struct amba_id pl010_ids[] = { |
770 | { | 781 | { |
771 | .id = 0x00041010, | 782 | .id = 0x00041010, |
772 | .mask = 0x000fffff, | 783 | .mask = 0x000fffff, |
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c index bf82e28770a9..e76d7d000128 100644 --- a/drivers/serial/amba-pl011.c +++ b/drivers/serial/amba-pl011.c | |||
@@ -7,6 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Copyright 1999 ARM Limited | 8 | * Copyright 1999 ARM Limited |
9 | * Copyright (C) 2000 Deep Blue Solutions Ltd. | 9 | * Copyright (C) 2000 Deep Blue Solutions Ltd. |
10 | * Copyright (C) 2010 ST-Ericsson SA | ||
10 | * | 11 | * |
11 | * This program is free software; you can redistribute it and/or modify | 12 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License as published by | 13 | * it under the terms of the GNU General Public License as published by |
@@ -47,6 +48,10 @@ | |||
47 | #include <linux/amba/bus.h> | 48 | #include <linux/amba/bus.h> |
48 | #include <linux/amba/serial.h> | 49 | #include <linux/amba/serial.h> |
49 | #include <linux/clk.h> | 50 | #include <linux/clk.h> |
51 | #include <linux/slab.h> | ||
52 | #include <linux/dmaengine.h> | ||
53 | #include <linux/dma-mapping.h> | ||
54 | #include <linux/scatterlist.h> | ||
50 | 55 | ||
51 | #include <asm/io.h> | 56 | #include <asm/io.h> |
52 | #include <asm/sizes.h> | 57 | #include <asm/sizes.h> |
@@ -62,47 +67,560 @@ | |||
62 | #define UART_DR_ERROR (UART011_DR_OE|UART011_DR_BE|UART011_DR_PE|UART011_DR_FE) | 67 | #define UART_DR_ERROR (UART011_DR_OE|UART011_DR_BE|UART011_DR_PE|UART011_DR_FE) |
63 | #define UART_DUMMY_DR_RX (1 << 16) | 68 | #define UART_DUMMY_DR_RX (1 << 16) |
64 | 69 | ||
65 | /* | ||
66 | * We wrap our port structure around the generic uart_port. | ||
67 | */ | ||
68 | struct uart_amba_port { | ||
69 | struct uart_port port; | ||
70 | struct clk *clk; | ||
71 | unsigned int im; /* interrupt mask */ | ||
72 | unsigned int old_status; | ||
73 | unsigned int ifls; /* vendor-specific */ | ||
74 | }; | ||
75 | |||
76 | /* There is by now at least one vendor with differing details, so handle it */ | 70 | /* There is by now at least one vendor with differing details, so handle it */ |
77 | struct vendor_data { | 71 | struct vendor_data { |
78 | unsigned int ifls; | 72 | unsigned int ifls; |
79 | unsigned int fifosize; | 73 | unsigned int fifosize; |
74 | unsigned int lcrh_tx; | ||
75 | unsigned int lcrh_rx; | ||
76 | bool oversampling; | ||
77 | bool dma_threshold; | ||
80 | }; | 78 | }; |
81 | 79 | ||
82 | static struct vendor_data vendor_arm = { | 80 | static struct vendor_data vendor_arm = { |
83 | .ifls = UART011_IFLS_RX4_8|UART011_IFLS_TX4_8, | 81 | .ifls = UART011_IFLS_RX4_8|UART011_IFLS_TX4_8, |
84 | .fifosize = 16, | 82 | .fifosize = 16, |
83 | .lcrh_tx = UART011_LCRH, | ||
84 | .lcrh_rx = UART011_LCRH, | ||
85 | .oversampling = false, | ||
86 | .dma_threshold = false, | ||
85 | }; | 87 | }; |
86 | 88 | ||
87 | static struct vendor_data vendor_st = { | 89 | static struct vendor_data vendor_st = { |
88 | .ifls = UART011_IFLS_RX_HALF|UART011_IFLS_TX_HALF, | 90 | .ifls = UART011_IFLS_RX_HALF|UART011_IFLS_TX_HALF, |
89 | .fifosize = 64, | 91 | .fifosize = 64, |
92 | .lcrh_tx = ST_UART011_LCRH_TX, | ||
93 | .lcrh_rx = ST_UART011_LCRH_RX, | ||
94 | .oversampling = true, | ||
95 | .dma_threshold = true, | ||
90 | }; | 96 | }; |
91 | 97 | ||
98 | /* Deals with DMA transactions */ | ||
99 | struct pl011_dmatx_data { | ||
100 | struct dma_chan *chan; | ||
101 | struct scatterlist sg; | ||
102 | char *buf; | ||
103 | bool queued; | ||
104 | }; | ||
105 | |||
106 | /* | ||
107 | * We wrap our port structure around the generic uart_port. | ||
108 | */ | ||
109 | struct uart_amba_port { | ||
110 | struct uart_port port; | ||
111 | struct clk *clk; | ||
112 | const struct vendor_data *vendor; | ||
113 | unsigned int dmacr; /* dma control reg */ | ||
114 | unsigned int im; /* interrupt mask */ | ||
115 | unsigned int old_status; | ||
116 | unsigned int fifosize; /* vendor-specific */ | ||
117 | unsigned int lcrh_tx; /* vendor-specific */ | ||
118 | unsigned int lcrh_rx; /* vendor-specific */ | ||
119 | bool autorts; | ||
120 | char type[12]; | ||
121 | #ifdef CONFIG_DMA_ENGINE | ||
122 | /* DMA stuff */ | ||
123 | bool using_dma; | ||
124 | struct pl011_dmatx_data dmatx; | ||
125 | #endif | ||
126 | }; | ||
127 | |||
128 | /* | ||
129 | * All the DMA operation mode stuff goes inside this ifdef. | ||
130 | * This assumes that you have a generic DMA device interface, | ||
131 | * no custom DMA interfaces are supported. | ||
132 | */ | ||
133 | #ifdef CONFIG_DMA_ENGINE | ||
134 | |||
135 | #define PL011_DMA_BUFFER_SIZE PAGE_SIZE | ||
136 | |||
137 | static void pl011_dma_probe_initcall(struct uart_amba_port *uap) | ||
138 | { | ||
139 | /* DMA is the sole user of the platform data right now */ | ||
140 | struct amba_pl011_data *plat = uap->port.dev->platform_data; | ||
141 | struct dma_slave_config tx_conf = { | ||
142 | .dst_addr = uap->port.mapbase + UART01x_DR, | ||
143 | .dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE, | ||
144 | .direction = DMA_TO_DEVICE, | ||
145 | .dst_maxburst = uap->fifosize >> 1, | ||
146 | }; | ||
147 | struct dma_chan *chan; | ||
148 | dma_cap_mask_t mask; | ||
149 | |||
150 | /* We need platform data */ | ||
151 | if (!plat || !plat->dma_filter) { | ||
152 | dev_info(uap->port.dev, "no DMA platform data\n"); | ||
153 | return; | ||
154 | } | ||
155 | |||
156 | /* Try to acquire a generic DMA engine slave channel */ | ||
157 | dma_cap_zero(mask); | ||
158 | dma_cap_set(DMA_SLAVE, mask); | ||
159 | |||
160 | chan = dma_request_channel(mask, plat->dma_filter, plat->dma_tx_param); | ||
161 | if (!chan) { | ||
162 | dev_err(uap->port.dev, "no TX DMA channel!\n"); | ||
163 | return; | ||
164 | } | ||
165 | |||
166 | dmaengine_slave_config(chan, &tx_conf); | ||
167 | uap->dmatx.chan = chan; | ||
168 | |||
169 | dev_info(uap->port.dev, "DMA channel TX %s\n", | ||
170 | dma_chan_name(uap->dmatx.chan)); | ||
171 | } | ||
172 | |||
173 | #ifndef MODULE | ||
174 | /* | ||
175 | * Stack up the UARTs and let the above initcall be done at device | ||
176 | * initcall time, because the serial driver is called as an arch | ||
177 | * initcall, and at this time the DMA subsystem is not yet registered. | ||
178 | * At this point the driver will switch over to using DMA where desired. | ||
179 | */ | ||
180 | struct dma_uap { | ||
181 | struct list_head node; | ||
182 | struct uart_amba_port *uap; | ||
183 | }; | ||
184 | |||
185 | static LIST_HEAD(pl011_dma_uarts); | ||
186 | |||
187 | static int __init pl011_dma_initcall(void) | ||
188 | { | ||
189 | struct list_head *node, *tmp; | ||
190 | |||
191 | list_for_each_safe(node, tmp, &pl011_dma_uarts) { | ||
192 | struct dma_uap *dmau = list_entry(node, struct dma_uap, node); | ||
193 | pl011_dma_probe_initcall(dmau->uap); | ||
194 | list_del(node); | ||
195 | kfree(dmau); | ||
196 | } | ||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | device_initcall(pl011_dma_initcall); | ||
201 | |||
202 | static void pl011_dma_probe(struct uart_amba_port *uap) | ||
203 | { | ||
204 | struct dma_uap *dmau = kzalloc(sizeof(struct dma_uap), GFP_KERNEL); | ||
205 | if (dmau) { | ||
206 | dmau->uap = uap; | ||
207 | list_add_tail(&dmau->node, &pl011_dma_uarts); | ||
208 | } | ||
209 | } | ||
210 | #else | ||
211 | static void pl011_dma_probe(struct uart_amba_port *uap) | ||
212 | { | ||
213 | pl011_dma_probe_initcall(uap); | ||
214 | } | ||
215 | #endif | ||
216 | |||
217 | static void pl011_dma_remove(struct uart_amba_port *uap) | ||
218 | { | ||
219 | /* TODO: remove the initcall if it has not yet executed */ | ||
220 | if (uap->dmatx.chan) | ||
221 | dma_release_channel(uap->dmatx.chan); | ||
222 | } | ||
223 | |||
224 | |||
225 | /* Forward declare this for the refill routine */ | ||
226 | static int pl011_dma_tx_refill(struct uart_amba_port *uap); | ||
227 | |||
228 | /* | ||
229 | * The current DMA TX buffer has been sent. | ||
230 | * Try to queue up another DMA buffer. | ||
231 | */ | ||
232 | static void pl011_dma_tx_callback(void *data) | ||
233 | { | ||
234 | struct uart_amba_port *uap = data; | ||
235 | struct pl011_dmatx_data *dmatx = &uap->dmatx; | ||
236 | unsigned long flags; | ||
237 | u16 dmacr; | ||
238 | |||
239 | spin_lock_irqsave(&uap->port.lock, flags); | ||
240 | if (uap->dmatx.queued) | ||
241 | dma_unmap_sg(dmatx->chan->device->dev, &dmatx->sg, 1, | ||
242 | DMA_TO_DEVICE); | ||
243 | |||
244 | dmacr = uap->dmacr; | ||
245 | uap->dmacr = dmacr & ~UART011_TXDMAE; | ||
246 | writew(uap->dmacr, uap->port.membase + UART011_DMACR); | ||
247 | |||
248 | /* | ||
249 | * If TX DMA was disabled, it means that we've stopped the DMA for | ||
250 | * some reason (eg, XOFF received, or we want to send an X-char.) | ||
251 | * | ||
252 | * Note: we need to be careful here of a potential race between DMA | ||
253 | * and the rest of the driver - if the driver disables TX DMA while | ||
254 | * a TX buffer completing, we must update the tx queued status to | ||
255 | * get further refills (hence we check dmacr). | ||
256 | */ | ||
257 | if (!(dmacr & UART011_TXDMAE) || uart_tx_stopped(&uap->port) || | ||
258 | uart_circ_empty(&uap->port.state->xmit)) { | ||
259 | uap->dmatx.queued = false; | ||
260 | spin_unlock_irqrestore(&uap->port.lock, flags); | ||
261 | return; | ||
262 | } | ||
263 | |||
264 | if (pl011_dma_tx_refill(uap) <= 0) { | ||
265 | /* | ||
266 | * We didn't queue a DMA buffer for some reason, but we | ||
267 | * have data pending to be sent. Re-enable the TX IRQ. | ||
268 | */ | ||
269 | uap->im |= UART011_TXIM; | ||
270 | writew(uap->im, uap->port.membase + UART011_IMSC); | ||
271 | } | ||
272 | spin_unlock_irqrestore(&uap->port.lock, flags); | ||
273 | } | ||
274 | |||
275 | /* | ||
276 | * Try to refill the TX DMA buffer. | ||
277 | * Locking: called with port lock held and IRQs disabled. | ||
278 | * Returns: | ||
279 | * 1 if we queued up a TX DMA buffer. | ||
280 | * 0 if we didn't want to handle this by DMA | ||
281 | * <0 on error | ||
282 | */ | ||
283 | static int pl011_dma_tx_refill(struct uart_amba_port *uap) | ||
284 | { | ||
285 | struct pl011_dmatx_data *dmatx = &uap->dmatx; | ||
286 | struct dma_chan *chan = dmatx->chan; | ||
287 | struct dma_device *dma_dev = chan->device; | ||
288 | struct dma_async_tx_descriptor *desc; | ||
289 | struct circ_buf *xmit = &uap->port.state->xmit; | ||
290 | unsigned int count; | ||
291 | |||
292 | /* | ||
293 | * Try to avoid the overhead involved in using DMA if the | ||
294 | * transaction fits in the first half of the FIFO, by using | ||
295 | * the standard interrupt handling. This ensures that we | ||
296 | * issue a uart_write_wakeup() at the appropriate time. | ||
297 | */ | ||
298 | count = uart_circ_chars_pending(xmit); | ||
299 | if (count < (uap->fifosize >> 1)) { | ||
300 | uap->dmatx.queued = false; | ||
301 | return 0; | ||
302 | } | ||
303 | |||
304 | /* | ||
305 | * Bodge: don't send the last character by DMA, as this | ||
306 | * will prevent XON from notifying us to restart DMA. | ||
307 | */ | ||
308 | count -= 1; | ||
309 | |||
310 | /* Else proceed to copy the TX chars to the DMA buffer and fire DMA */ | ||
311 | if (count > PL011_DMA_BUFFER_SIZE) | ||
312 | count = PL011_DMA_BUFFER_SIZE; | ||
313 | |||
314 | if (xmit->tail < xmit->head) | ||
315 | memcpy(&dmatx->buf[0], &xmit->buf[xmit->tail], count); | ||
316 | else { | ||
317 | size_t first = UART_XMIT_SIZE - xmit->tail; | ||
318 | size_t second = xmit->head; | ||
319 | |||
320 | memcpy(&dmatx->buf[0], &xmit->buf[xmit->tail], first); | ||
321 | if (second) | ||
322 | memcpy(&dmatx->buf[first], &xmit->buf[0], second); | ||
323 | } | ||
324 | |||
325 | dmatx->sg.length = count; | ||
326 | |||
327 | if (dma_map_sg(dma_dev->dev, &dmatx->sg, 1, DMA_TO_DEVICE) != 1) { | ||
328 | uap->dmatx.queued = false; | ||
329 | dev_dbg(uap->port.dev, "unable to map TX DMA\n"); | ||
330 | return -EBUSY; | ||
331 | } | ||
332 | |||
333 | desc = dma_dev->device_prep_slave_sg(chan, &dmatx->sg, 1, DMA_TO_DEVICE, | ||
334 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
335 | if (!desc) { | ||
336 | dma_unmap_sg(dma_dev->dev, &dmatx->sg, 1, DMA_TO_DEVICE); | ||
337 | uap->dmatx.queued = false; | ||
338 | /* | ||
339 | * If DMA cannot be used right now, we complete this | ||
340 | * transaction via IRQ and let the TTY layer retry. | ||
341 | */ | ||
342 | dev_dbg(uap->port.dev, "TX DMA busy\n"); | ||
343 | return -EBUSY; | ||
344 | } | ||
345 | |||
346 | /* Some data to go along to the callback */ | ||
347 | desc->callback = pl011_dma_tx_callback; | ||
348 | desc->callback_param = uap; | ||
349 | |||
350 | /* All errors should happen at prepare time */ | ||
351 | dmaengine_submit(desc); | ||
352 | |||
353 | /* Fire the DMA transaction */ | ||
354 | dma_dev->device_issue_pending(chan); | ||
355 | |||
356 | uap->dmacr |= UART011_TXDMAE; | ||
357 | writew(uap->dmacr, uap->port.membase + UART011_DMACR); | ||
358 | uap->dmatx.queued = true; | ||
359 | |||
360 | /* | ||
361 | * Now we know that DMA will fire, so advance the ring buffer | ||
362 | * with the stuff we just dispatched. | ||
363 | */ | ||
364 | xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); | ||
365 | uap->port.icount.tx += count; | ||
366 | |||
367 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
368 | uart_write_wakeup(&uap->port); | ||
369 | |||
370 | return 1; | ||
371 | } | ||
372 | |||
373 | /* | ||
374 | * We received a transmit interrupt without a pending X-char but with | ||
375 | * pending characters. | ||
376 | * Locking: called with port lock held and IRQs disabled. | ||
377 | * Returns: | ||
378 | * false if we want to use PIO to transmit | ||
379 | * true if we queued a DMA buffer | ||
380 | */ | ||
381 | static bool pl011_dma_tx_irq(struct uart_amba_port *uap) | ||
382 | { | ||
383 | if (!uap->using_dma) | ||
384 | return false; | ||
385 | |||
386 | /* | ||
387 | * If we already have a TX buffer queued, but received a | ||
388 | * TX interrupt, it will be because we've just sent an X-char. | ||
389 | * Ensure the TX DMA is enabled and the TX IRQ is disabled. | ||
390 | */ | ||
391 | if (uap->dmatx.queued) { | ||
392 | uap->dmacr |= UART011_TXDMAE; | ||
393 | writew(uap->dmacr, uap->port.membase + UART011_DMACR); | ||
394 | uap->im &= ~UART011_TXIM; | ||
395 | writew(uap->im, uap->port.membase + UART011_IMSC); | ||
396 | return true; | ||
397 | } | ||
398 | |||
399 | /* | ||
400 | * We don't have a TX buffer queued, so try to queue one. | ||
401 | * If we succesfully queued a buffer, mask the TX IRQ. | ||
402 | */ | ||
403 | if (pl011_dma_tx_refill(uap) > 0) { | ||
404 | uap->im &= ~UART011_TXIM; | ||
405 | writew(uap->im, uap->port.membase + UART011_IMSC); | ||
406 | return true; | ||
407 | } | ||
408 | return false; | ||
409 | } | ||
410 | |||
411 | /* | ||
412 | * Stop the DMA transmit (eg, due to received XOFF). | ||
413 | * Locking: called with port lock held and IRQs disabled. | ||
414 | */ | ||
415 | static inline void pl011_dma_tx_stop(struct uart_amba_port *uap) | ||
416 | { | ||
417 | if (uap->dmatx.queued) { | ||
418 | uap->dmacr &= ~UART011_TXDMAE; | ||
419 | writew(uap->dmacr, uap->port.membase + UART011_DMACR); | ||
420 | } | ||
421 | } | ||
422 | |||
423 | /* | ||
424 | * Try to start a DMA transmit, or in the case of an XON/OFF | ||
425 | * character queued for send, try to get that character out ASAP. | ||
426 | * Locking: called with port lock held and IRQs disabled. | ||
427 | * Returns: | ||
428 | * false if we want the TX IRQ to be enabled | ||
429 | * true if we have a buffer queued | ||
430 | */ | ||
431 | static inline bool pl011_dma_tx_start(struct uart_amba_port *uap) | ||
432 | { | ||
433 | u16 dmacr; | ||
434 | |||
435 | if (!uap->using_dma) | ||
436 | return false; | ||
437 | |||
438 | if (!uap->port.x_char) { | ||
439 | /* no X-char, try to push chars out in DMA mode */ | ||
440 | bool ret = true; | ||
441 | |||
442 | if (!uap->dmatx.queued) { | ||
443 | if (pl011_dma_tx_refill(uap) > 0) { | ||
444 | uap->im &= ~UART011_TXIM; | ||
445 | ret = true; | ||
446 | } else { | ||
447 | uap->im |= UART011_TXIM; | ||
448 | ret = false; | ||
449 | } | ||
450 | writew(uap->im, uap->port.membase + UART011_IMSC); | ||
451 | } else if (!(uap->dmacr & UART011_TXDMAE)) { | ||
452 | uap->dmacr |= UART011_TXDMAE; | ||
453 | writew(uap->dmacr, | ||
454 | uap->port.membase + UART011_DMACR); | ||
455 | } | ||
456 | return ret; | ||
457 | } | ||
458 | |||
459 | /* | ||
460 | * We have an X-char to send. Disable DMA to prevent it loading | ||
461 | * the TX fifo, and then see if we can stuff it into the FIFO. | ||
462 | */ | ||
463 | dmacr = uap->dmacr; | ||
464 | uap->dmacr &= ~UART011_TXDMAE; | ||
465 | writew(uap->dmacr, uap->port.membase + UART011_DMACR); | ||
466 | |||
467 | if (readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF) { | ||
468 | /* | ||
469 | * No space in the FIFO, so enable the transmit interrupt | ||
470 | * so we know when there is space. Note that once we've | ||
471 | * loaded the character, we should just re-enable DMA. | ||
472 | */ | ||
473 | return false; | ||
474 | } | ||
475 | |||
476 | writew(uap->port.x_char, uap->port.membase + UART01x_DR); | ||
477 | uap->port.icount.tx++; | ||
478 | uap->port.x_char = 0; | ||
479 | |||
480 | /* Success - restore the DMA state */ | ||
481 | uap->dmacr = dmacr; | ||
482 | writew(dmacr, uap->port.membase + UART011_DMACR); | ||
483 | |||
484 | return true; | ||
485 | } | ||
486 | |||
487 | /* | ||
488 | * Flush the transmit buffer. | ||
489 | * Locking: called with port lock held and IRQs disabled. | ||
490 | */ | ||
491 | static void pl011_dma_flush_buffer(struct uart_port *port) | ||
492 | { | ||
493 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | ||
494 | |||
495 | if (!uap->using_dma) | ||
496 | return; | ||
497 | |||
498 | /* Avoid deadlock with the DMA engine callback */ | ||
499 | spin_unlock(&uap->port.lock); | ||
500 | dmaengine_terminate_all(uap->dmatx.chan); | ||
501 | spin_lock(&uap->port.lock); | ||
502 | if (uap->dmatx.queued) { | ||
503 | dma_unmap_sg(uap->dmatx.chan->device->dev, &uap->dmatx.sg, 1, | ||
504 | DMA_TO_DEVICE); | ||
505 | uap->dmatx.queued = false; | ||
506 | uap->dmacr &= ~UART011_TXDMAE; | ||
507 | writew(uap->dmacr, uap->port.membase + UART011_DMACR); | ||
508 | } | ||
509 | } | ||
510 | |||
511 | |||
512 | static void pl011_dma_startup(struct uart_amba_port *uap) | ||
513 | { | ||
514 | if (!uap->dmatx.chan) | ||
515 | return; | ||
516 | |||
517 | uap->dmatx.buf = kmalloc(PL011_DMA_BUFFER_SIZE, GFP_KERNEL); | ||
518 | if (!uap->dmatx.buf) { | ||
519 | dev_err(uap->port.dev, "no memory for DMA TX buffer\n"); | ||
520 | uap->port.fifosize = uap->fifosize; | ||
521 | return; | ||
522 | } | ||
523 | |||
524 | sg_init_one(&uap->dmatx.sg, uap->dmatx.buf, PL011_DMA_BUFFER_SIZE); | ||
525 | |||
526 | /* The DMA buffer is now the FIFO the TTY subsystem can use */ | ||
527 | uap->port.fifosize = PL011_DMA_BUFFER_SIZE; | ||
528 | uap->using_dma = true; | ||
529 | |||
530 | /* Turn on DMA error (RX/TX will be enabled on demand) */ | ||
531 | uap->dmacr |= UART011_DMAONERR; | ||
532 | writew(uap->dmacr, uap->port.membase + UART011_DMACR); | ||
533 | |||
534 | /* | ||
535 | * ST Micro variants has some specific dma burst threshold | ||
536 | * compensation. Set this to 16 bytes, so burst will only | ||
537 | * be issued above/below 16 bytes. | ||
538 | */ | ||
539 | if (uap->vendor->dma_threshold) | ||
540 | writew(ST_UART011_DMAWM_RX_16 | ST_UART011_DMAWM_TX_16, | ||
541 | uap->port.membase + ST_UART011_DMAWM); | ||
542 | } | ||
543 | |||
544 | static void pl011_dma_shutdown(struct uart_amba_port *uap) | ||
545 | { | ||
546 | if (!uap->using_dma) | ||
547 | return; | ||
548 | |||
549 | /* Disable RX and TX DMA */ | ||
550 | while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_BUSY) | ||
551 | barrier(); | ||
552 | |||
553 | spin_lock_irq(&uap->port.lock); | ||
554 | uap->dmacr &= ~(UART011_DMAONERR | UART011_RXDMAE | UART011_TXDMAE); | ||
555 | writew(uap->dmacr, uap->port.membase + UART011_DMACR); | ||
556 | spin_unlock_irq(&uap->port.lock); | ||
557 | |||
558 | /* In theory, this should already be done by pl011_dma_flush_buffer */ | ||
559 | dmaengine_terminate_all(uap->dmatx.chan); | ||
560 | if (uap->dmatx.queued) { | ||
561 | dma_unmap_sg(uap->dmatx.chan->device->dev, &uap->dmatx.sg, 1, | ||
562 | DMA_TO_DEVICE); | ||
563 | uap->dmatx.queued = false; | ||
564 | } | ||
565 | |||
566 | kfree(uap->dmatx.buf); | ||
567 | |||
568 | uap->using_dma = false; | ||
569 | } | ||
570 | |||
571 | #else | ||
572 | /* Blank functions if the DMA engine is not available */ | ||
573 | static inline void pl011_dma_probe(struct uart_amba_port *uap) | ||
574 | { | ||
575 | } | ||
576 | |||
577 | static inline void pl011_dma_remove(struct uart_amba_port *uap) | ||
578 | { | ||
579 | } | ||
580 | |||
581 | static inline void pl011_dma_startup(struct uart_amba_port *uap) | ||
582 | { | ||
583 | } | ||
584 | |||
585 | static inline void pl011_dma_shutdown(struct uart_amba_port *uap) | ||
586 | { | ||
587 | } | ||
588 | |||
589 | static inline bool pl011_dma_tx_irq(struct uart_amba_port *uap) | ||
590 | { | ||
591 | return false; | ||
592 | } | ||
593 | |||
594 | static inline void pl011_dma_tx_stop(struct uart_amba_port *uap) | ||
595 | { | ||
596 | } | ||
597 | |||
598 | static inline bool pl011_dma_tx_start(struct uart_amba_port *uap) | ||
599 | { | ||
600 | return false; | ||
601 | } | ||
602 | |||
603 | #define pl011_dma_flush_buffer NULL | ||
604 | #endif | ||
605 | |||
606 | |||
92 | static void pl011_stop_tx(struct uart_port *port) | 607 | static void pl011_stop_tx(struct uart_port *port) |
93 | { | 608 | { |
94 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 609 | struct uart_amba_port *uap = (struct uart_amba_port *)port; |
95 | 610 | ||
96 | uap->im &= ~UART011_TXIM; | 611 | uap->im &= ~UART011_TXIM; |
97 | writew(uap->im, uap->port.membase + UART011_IMSC); | 612 | writew(uap->im, uap->port.membase + UART011_IMSC); |
613 | pl011_dma_tx_stop(uap); | ||
98 | } | 614 | } |
99 | 615 | ||
100 | static void pl011_start_tx(struct uart_port *port) | 616 | static void pl011_start_tx(struct uart_port *port) |
101 | { | 617 | { |
102 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 618 | struct uart_amba_port *uap = (struct uart_amba_port *)port; |
103 | 619 | ||
104 | uap->im |= UART011_TXIM; | 620 | if (!pl011_dma_tx_start(uap)) { |
105 | writew(uap->im, uap->port.membase + UART011_IMSC); | 621 | uap->im |= UART011_TXIM; |
622 | writew(uap->im, uap->port.membase + UART011_IMSC); | ||
623 | } | ||
106 | } | 624 | } |
107 | 625 | ||
108 | static void pl011_stop_rx(struct uart_port *port) | 626 | static void pl011_stop_rx(struct uart_port *port) |
@@ -124,7 +642,7 @@ static void pl011_enable_ms(struct uart_port *port) | |||
124 | 642 | ||
125 | static void pl011_rx_chars(struct uart_amba_port *uap) | 643 | static void pl011_rx_chars(struct uart_amba_port *uap) |
126 | { | 644 | { |
127 | struct tty_struct *tty = uap->port.info->port.tty; | 645 | struct tty_struct *tty = uap->port.state->port.tty; |
128 | unsigned int status, ch, flag, max_count = 256; | 646 | unsigned int status, ch, flag, max_count = 256; |
129 | 647 | ||
130 | status = readw(uap->port.membase + UART01x_FR); | 648 | status = readw(uap->port.membase + UART01x_FR); |
@@ -175,7 +693,7 @@ static void pl011_rx_chars(struct uart_amba_port *uap) | |||
175 | 693 | ||
176 | static void pl011_tx_chars(struct uart_amba_port *uap) | 694 | static void pl011_tx_chars(struct uart_amba_port *uap) |
177 | { | 695 | { |
178 | struct circ_buf *xmit = &uap->port.info->xmit; | 696 | struct circ_buf *xmit = &uap->port.state->xmit; |
179 | int count; | 697 | int count; |
180 | 698 | ||
181 | if (uap->port.x_char) { | 699 | if (uap->port.x_char) { |
@@ -189,7 +707,11 @@ static void pl011_tx_chars(struct uart_amba_port *uap) | |||
189 | return; | 707 | return; |
190 | } | 708 | } |
191 | 709 | ||
192 | count = uap->port.fifosize >> 1; | 710 | /* If we are using DMA mode, try to send some characters. */ |
711 | if (pl011_dma_tx_irq(uap)) | ||
712 | return; | ||
713 | |||
714 | count = uap->fifosize >> 1; | ||
193 | do { | 715 | do { |
194 | writew(xmit->buf[xmit->tail], uap->port.membase + UART01x_DR); | 716 | writew(xmit->buf[xmit->tail], uap->port.membase + UART01x_DR); |
195 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | 717 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); |
@@ -226,16 +748,17 @@ static void pl011_modem_status(struct uart_amba_port *uap) | |||
226 | if (delta & UART01x_FR_CTS) | 748 | if (delta & UART01x_FR_CTS) |
227 | uart_handle_cts_change(&uap->port, status & UART01x_FR_CTS); | 749 | uart_handle_cts_change(&uap->port, status & UART01x_FR_CTS); |
228 | 750 | ||
229 | wake_up_interruptible(&uap->port.info->delta_msr_wait); | 751 | wake_up_interruptible(&uap->port.state->port.delta_msr_wait); |
230 | } | 752 | } |
231 | 753 | ||
232 | static irqreturn_t pl011_int(int irq, void *dev_id) | 754 | static irqreturn_t pl011_int(int irq, void *dev_id) |
233 | { | 755 | { |
234 | struct uart_amba_port *uap = dev_id; | 756 | struct uart_amba_port *uap = dev_id; |
757 | unsigned long flags; | ||
235 | unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT; | 758 | unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT; |
236 | int handled = 0; | 759 | int handled = 0; |
237 | 760 | ||
238 | spin_lock(&uap->port.lock); | 761 | spin_lock_irqsave(&uap->port.lock, flags); |
239 | 762 | ||
240 | status = readw(uap->port.membase + UART011_MIS); | 763 | status = readw(uap->port.membase + UART011_MIS); |
241 | if (status) { | 764 | if (status) { |
@@ -260,7 +783,7 @@ static irqreturn_t pl011_int(int irq, void *dev_id) | |||
260 | handled = 1; | 783 | handled = 1; |
261 | } | 784 | } |
262 | 785 | ||
263 | spin_unlock(&uap->port.lock); | 786 | spin_unlock_irqrestore(&uap->port.lock, flags); |
264 | 787 | ||
265 | return IRQ_RETVAL(handled); | 788 | return IRQ_RETVAL(handled); |
266 | } | 789 | } |
@@ -308,6 +831,11 @@ static void pl011_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
308 | TIOCMBIT(TIOCM_OUT1, UART011_CR_OUT1); | 831 | TIOCMBIT(TIOCM_OUT1, UART011_CR_OUT1); |
309 | TIOCMBIT(TIOCM_OUT2, UART011_CR_OUT2); | 832 | TIOCMBIT(TIOCM_OUT2, UART011_CR_OUT2); |
310 | TIOCMBIT(TIOCM_LOOP, UART011_CR_LBE); | 833 | TIOCMBIT(TIOCM_LOOP, UART011_CR_LBE); |
834 | |||
835 | if (uap->autorts) { | ||
836 | /* We need to disable auto-RTS if we want to turn RTS off */ | ||
837 | TIOCMBIT(TIOCM_RTS, UART011_CR_RTSEN); | ||
838 | } | ||
311 | #undef TIOCMBIT | 839 | #undef TIOCMBIT |
312 | 840 | ||
313 | writew(cr, uap->port.membase + UART011_CR); | 841 | writew(cr, uap->port.membase + UART011_CR); |
@@ -320,12 +848,12 @@ static void pl011_break_ctl(struct uart_port *port, int break_state) | |||
320 | unsigned int lcr_h; | 848 | unsigned int lcr_h; |
321 | 849 | ||
322 | spin_lock_irqsave(&uap->port.lock, flags); | 850 | spin_lock_irqsave(&uap->port.lock, flags); |
323 | lcr_h = readw(uap->port.membase + UART011_LCRH); | 851 | lcr_h = readw(uap->port.membase + uap->lcrh_tx); |
324 | if (break_state == -1) | 852 | if (break_state == -1) |
325 | lcr_h |= UART01x_LCRH_BRK; | 853 | lcr_h |= UART01x_LCRH_BRK; |
326 | else | 854 | else |
327 | lcr_h &= ~UART01x_LCRH_BRK; | 855 | lcr_h &= ~UART01x_LCRH_BRK; |
328 | writew(lcr_h, uap->port.membase + UART011_LCRH); | 856 | writew(lcr_h, uap->port.membase + uap->lcrh_tx); |
329 | spin_unlock_irqrestore(&uap->port.lock, flags); | 857 | spin_unlock_irqrestore(&uap->port.lock, flags); |
330 | } | 858 | } |
331 | 859 | ||
@@ -335,9 +863,9 @@ static int pl010_get_poll_char(struct uart_port *port) | |||
335 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 863 | struct uart_amba_port *uap = (struct uart_amba_port *)port; |
336 | unsigned int status; | 864 | unsigned int status; |
337 | 865 | ||
338 | do { | 866 | status = readw(uap->port.membase + UART01x_FR); |
339 | status = readw(uap->port.membase + UART01x_FR); | 867 | if (status & UART01x_FR_RXFE) |
340 | } while (status & UART01x_FR_RXFE); | 868 | return NO_POLL_CHAR; |
341 | 869 | ||
342 | return readw(uap->port.membase + UART01x_DR); | 870 | return readw(uap->port.membase + UART01x_DR); |
343 | } | 871 | } |
@@ -377,7 +905,7 @@ static int pl011_startup(struct uart_port *port) | |||
377 | if (retval) | 905 | if (retval) |
378 | goto clk_dis; | 906 | goto clk_dis; |
379 | 907 | ||
380 | writew(uap->ifls, uap->port.membase + UART011_IFLS); | 908 | writew(uap->vendor->ifls, uap->port.membase + UART011_IFLS); |
381 | 909 | ||
382 | /* | 910 | /* |
383 | * Provoke TX FIFO interrupt into asserting. | 911 | * Provoke TX FIFO interrupt into asserting. |
@@ -386,7 +914,17 @@ static int pl011_startup(struct uart_port *port) | |||
386 | writew(cr, uap->port.membase + UART011_CR); | 914 | writew(cr, uap->port.membase + UART011_CR); |
387 | writew(0, uap->port.membase + UART011_FBRD); | 915 | writew(0, uap->port.membase + UART011_FBRD); |
388 | writew(1, uap->port.membase + UART011_IBRD); | 916 | writew(1, uap->port.membase + UART011_IBRD); |
389 | writew(0, uap->port.membase + UART011_LCRH); | 917 | writew(0, uap->port.membase + uap->lcrh_rx); |
918 | if (uap->lcrh_tx != uap->lcrh_rx) { | ||
919 | int i; | ||
920 | /* | ||
921 | * Wait 10 PCLKs before writing LCRH_TX register, | ||
922 | * to get this delay write read only register 10 times | ||
923 | */ | ||
924 | for (i = 0; i < 10; ++i) | ||
925 | writew(0xff, uap->port.membase + UART011_MIS); | ||
926 | writew(0, uap->port.membase + uap->lcrh_tx); | ||
927 | } | ||
390 | writew(0, uap->port.membase + UART01x_DR); | 928 | writew(0, uap->port.membase + UART01x_DR); |
391 | while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_BUSY) | 929 | while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_BUSY) |
392 | barrier(); | 930 | barrier(); |
@@ -394,11 +932,18 @@ static int pl011_startup(struct uart_port *port) | |||
394 | cr = UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE; | 932 | cr = UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE; |
395 | writew(cr, uap->port.membase + UART011_CR); | 933 | writew(cr, uap->port.membase + UART011_CR); |
396 | 934 | ||
935 | /* Clear pending error interrupts */ | ||
936 | writew(UART011_OEIS | UART011_BEIS | UART011_PEIS | UART011_FEIS, | ||
937 | uap->port.membase + UART011_ICR); | ||
938 | |||
397 | /* | 939 | /* |
398 | * initialise the old status of the modem signals | 940 | * initialise the old status of the modem signals |
399 | */ | 941 | */ |
400 | uap->old_status = readw(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY; | 942 | uap->old_status = readw(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY; |
401 | 943 | ||
944 | /* Startup DMA */ | ||
945 | pl011_dma_startup(uap); | ||
946 | |||
402 | /* | 947 | /* |
403 | * Finally, enable interrupts | 948 | * Finally, enable interrupts |
404 | */ | 949 | */ |
@@ -415,10 +960,19 @@ static int pl011_startup(struct uart_port *port) | |||
415 | return retval; | 960 | return retval; |
416 | } | 961 | } |
417 | 962 | ||
963 | static void pl011_shutdown_channel(struct uart_amba_port *uap, | ||
964 | unsigned int lcrh) | ||
965 | { | ||
966 | unsigned long val; | ||
967 | |||
968 | val = readw(uap->port.membase + lcrh); | ||
969 | val &= ~(UART01x_LCRH_BRK | UART01x_LCRH_FEN); | ||
970 | writew(val, uap->port.membase + lcrh); | ||
971 | } | ||
972 | |||
418 | static void pl011_shutdown(struct uart_port *port) | 973 | static void pl011_shutdown(struct uart_port *port) |
419 | { | 974 | { |
420 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 975 | struct uart_amba_port *uap = (struct uart_amba_port *)port; |
421 | unsigned long val; | ||
422 | 976 | ||
423 | /* | 977 | /* |
424 | * disable all interrupts | 978 | * disable all interrupts |
@@ -429,6 +983,8 @@ static void pl011_shutdown(struct uart_port *port) | |||
429 | writew(0xffff, uap->port.membase + UART011_ICR); | 983 | writew(0xffff, uap->port.membase + UART011_ICR); |
430 | spin_unlock_irq(&uap->port.lock); | 984 | spin_unlock_irq(&uap->port.lock); |
431 | 985 | ||
986 | pl011_dma_shutdown(uap); | ||
987 | |||
432 | /* | 988 | /* |
433 | * Free the interrupt | 989 | * Free the interrupt |
434 | */ | 990 | */ |
@@ -437,14 +993,15 @@ static void pl011_shutdown(struct uart_port *port) | |||
437 | /* | 993 | /* |
438 | * disable the port | 994 | * disable the port |
439 | */ | 995 | */ |
996 | uap->autorts = false; | ||
440 | writew(UART01x_CR_UARTEN | UART011_CR_TXE, uap->port.membase + UART011_CR); | 997 | writew(UART01x_CR_UARTEN | UART011_CR_TXE, uap->port.membase + UART011_CR); |
441 | 998 | ||
442 | /* | 999 | /* |
443 | * disable break condition and fifos | 1000 | * disable break condition and fifos |
444 | */ | 1001 | */ |
445 | val = readw(uap->port.membase + UART011_LCRH); | 1002 | pl011_shutdown_channel(uap, uap->lcrh_rx); |
446 | val &= ~(UART01x_LCRH_BRK | UART01x_LCRH_FEN); | 1003 | if (uap->lcrh_rx != uap->lcrh_tx) |
447 | writew(val, uap->port.membase + UART011_LCRH); | 1004 | pl011_shutdown_channel(uap, uap->lcrh_tx); |
448 | 1005 | ||
449 | /* | 1006 | /* |
450 | * Shut down the clock producer | 1007 | * Shut down the clock producer |
@@ -456,15 +1013,26 @@ static void | |||
456 | pl011_set_termios(struct uart_port *port, struct ktermios *termios, | 1013 | pl011_set_termios(struct uart_port *port, struct ktermios *termios, |
457 | struct ktermios *old) | 1014 | struct ktermios *old) |
458 | { | 1015 | { |
1016 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | ||
459 | unsigned int lcr_h, old_cr; | 1017 | unsigned int lcr_h, old_cr; |
460 | unsigned long flags; | 1018 | unsigned long flags; |
461 | unsigned int baud, quot; | 1019 | unsigned int baud, quot, clkdiv; |
1020 | |||
1021 | if (uap->vendor->oversampling) | ||
1022 | clkdiv = 8; | ||
1023 | else | ||
1024 | clkdiv = 16; | ||
462 | 1025 | ||
463 | /* | 1026 | /* |
464 | * Ask the core to calculate the divisor for us. | 1027 | * Ask the core to calculate the divisor for us. |
465 | */ | 1028 | */ |
466 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); | 1029 | baud = uart_get_baud_rate(port, termios, old, 0, |
467 | quot = port->uartclk * 4 / baud; | 1030 | port->uartclk / clkdiv); |
1031 | |||
1032 | if (baud > port->uartclk/16) | ||
1033 | quot = DIV_ROUND_CLOSEST(port->uartclk * 8, baud); | ||
1034 | else | ||
1035 | quot = DIV_ROUND_CLOSEST(port->uartclk * 4, baud); | ||
468 | 1036 | ||
469 | switch (termios->c_cflag & CSIZE) { | 1037 | switch (termios->c_cflag & CSIZE) { |
470 | case CS5: | 1038 | case CS5: |
@@ -487,7 +1055,7 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, | |||
487 | if (!(termios->c_cflag & PARODD)) | 1055 | if (!(termios->c_cflag & PARODD)) |
488 | lcr_h |= UART01x_LCRH_EPS; | 1056 | lcr_h |= UART01x_LCRH_EPS; |
489 | } | 1057 | } |
490 | if (port->fifosize > 1) | 1058 | if (uap->fifosize > 1) |
491 | lcr_h |= UART01x_LCRH_FEN; | 1059 | lcr_h |= UART01x_LCRH_FEN; |
492 | 1060 | ||
493 | spin_lock_irqsave(&port->lock, flags); | 1061 | spin_lock_irqsave(&port->lock, flags); |
@@ -532,6 +1100,24 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, | |||
532 | old_cr = readw(port->membase + UART011_CR); | 1100 | old_cr = readw(port->membase + UART011_CR); |
533 | writew(0, port->membase + UART011_CR); | 1101 | writew(0, port->membase + UART011_CR); |
534 | 1102 | ||
1103 | if (termios->c_cflag & CRTSCTS) { | ||
1104 | if (old_cr & UART011_CR_RTS) | ||
1105 | old_cr |= UART011_CR_RTSEN; | ||
1106 | |||
1107 | old_cr |= UART011_CR_CTSEN; | ||
1108 | uap->autorts = true; | ||
1109 | } else { | ||
1110 | old_cr &= ~(UART011_CR_CTSEN | UART011_CR_RTSEN); | ||
1111 | uap->autorts = false; | ||
1112 | } | ||
1113 | |||
1114 | if (uap->vendor->oversampling) { | ||
1115 | if (baud > port->uartclk / 16) | ||
1116 | old_cr |= ST_UART011_CR_OVSFACT; | ||
1117 | else | ||
1118 | old_cr &= ~ST_UART011_CR_OVSFACT; | ||
1119 | } | ||
1120 | |||
535 | /* Set baud rate */ | 1121 | /* Set baud rate */ |
536 | writew(quot & 0x3f, port->membase + UART011_FBRD); | 1122 | writew(quot & 0x3f, port->membase + UART011_FBRD); |
537 | writew(quot >> 6, port->membase + UART011_IBRD); | 1123 | writew(quot >> 6, port->membase + UART011_IBRD); |
@@ -541,7 +1127,17 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, | |||
541 | * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L | 1127 | * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L |
542 | * ----------^----------^----------^----------^----- | 1128 | * ----------^----------^----------^----------^----- |
543 | */ | 1129 | */ |
544 | writew(lcr_h, port->membase + UART011_LCRH); | 1130 | writew(lcr_h, port->membase + uap->lcrh_rx); |
1131 | if (uap->lcrh_rx != uap->lcrh_tx) { | ||
1132 | int i; | ||
1133 | /* | ||
1134 | * Wait 10 PCLKs before writing LCRH_TX register, | ||
1135 | * to get this delay write read only register 10 times | ||
1136 | */ | ||
1137 | for (i = 0; i < 10; ++i) | ||
1138 | writew(0xff, uap->port.membase + UART011_MIS); | ||
1139 | writew(lcr_h, port->membase + uap->lcrh_tx); | ||
1140 | } | ||
545 | writew(old_cr, port->membase + UART011_CR); | 1141 | writew(old_cr, port->membase + UART011_CR); |
546 | 1142 | ||
547 | spin_unlock_irqrestore(&port->lock, flags); | 1143 | spin_unlock_irqrestore(&port->lock, flags); |
@@ -549,7 +1145,8 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, | |||
549 | 1145 | ||
550 | static const char *pl011_type(struct uart_port *port) | 1146 | static const char *pl011_type(struct uart_port *port) |
551 | { | 1147 | { |
552 | return port->type == PORT_AMBA ? "AMBA/PL011" : NULL; | 1148 | struct uart_amba_port *uap = (struct uart_amba_port *)port; |
1149 | return uap->port.type == PORT_AMBA ? uap->type : NULL; | ||
553 | } | 1150 | } |
554 | 1151 | ||
555 | /* | 1152 | /* |
@@ -606,6 +1203,7 @@ static struct uart_ops amba_pl011_pops = { | |||
606 | .break_ctl = pl011_break_ctl, | 1203 | .break_ctl = pl011_break_ctl, |
607 | .startup = pl011_startup, | 1204 | .startup = pl011_startup, |
608 | .shutdown = pl011_shutdown, | 1205 | .shutdown = pl011_shutdown, |
1206 | .flush_buffer = pl011_dma_flush_buffer, | ||
609 | .set_termios = pl011_set_termios, | 1207 | .set_termios = pl011_set_termios, |
610 | .type = pl011_type, | 1208 | .type = pl011_type, |
611 | .release_port = pl010_release_port, | 1209 | .release_port = pl010_release_port, |
@@ -668,7 +1266,7 @@ pl011_console_get_options(struct uart_amba_port *uap, int *baud, | |||
668 | if (readw(uap->port.membase + UART011_CR) & UART01x_CR_UARTEN) { | 1266 | if (readw(uap->port.membase + UART011_CR) & UART01x_CR_UARTEN) { |
669 | unsigned int lcr_h, ibrd, fbrd; | 1267 | unsigned int lcr_h, ibrd, fbrd; |
670 | 1268 | ||
671 | lcr_h = readw(uap->port.membase + UART011_LCRH); | 1269 | lcr_h = readw(uap->port.membase + uap->lcrh_tx); |
672 | 1270 | ||
673 | *parity = 'n'; | 1271 | *parity = 'n'; |
674 | if (lcr_h & UART01x_LCRH_PEN) { | 1272 | if (lcr_h & UART01x_LCRH_PEN) { |
@@ -687,6 +1285,12 @@ pl011_console_get_options(struct uart_amba_port *uap, int *baud, | |||
687 | fbrd = readw(uap->port.membase + UART011_FBRD); | 1285 | fbrd = readw(uap->port.membase + UART011_FBRD); |
688 | 1286 | ||
689 | *baud = uap->port.uartclk * 4 / (64 * ibrd + fbrd); | 1287 | *baud = uap->port.uartclk * 4 / (64 * ibrd + fbrd); |
1288 | |||
1289 | if (uap->vendor->oversampling) { | ||
1290 | if (readw(uap->port.membase + UART011_CR) | ||
1291 | & ST_UART011_CR_OVSFACT) | ||
1292 | *baud *= 2; | ||
1293 | } | ||
690 | } | 1294 | } |
691 | } | 1295 | } |
692 | 1296 | ||
@@ -779,16 +1383,22 @@ static int pl011_probe(struct amba_device *dev, struct amba_id *id) | |||
779 | goto unmap; | 1383 | goto unmap; |
780 | } | 1384 | } |
781 | 1385 | ||
782 | uap->ifls = vendor->ifls; | 1386 | uap->vendor = vendor; |
1387 | uap->lcrh_rx = vendor->lcrh_rx; | ||
1388 | uap->lcrh_tx = vendor->lcrh_tx; | ||
1389 | uap->fifosize = vendor->fifosize; | ||
783 | uap->port.dev = &dev->dev; | 1390 | uap->port.dev = &dev->dev; |
784 | uap->port.mapbase = dev->res.start; | 1391 | uap->port.mapbase = dev->res.start; |
785 | uap->port.membase = base; | 1392 | uap->port.membase = base; |
786 | uap->port.iotype = UPIO_MEM; | 1393 | uap->port.iotype = UPIO_MEM; |
787 | uap->port.irq = dev->irq[0]; | 1394 | uap->port.irq = dev->irq[0]; |
788 | uap->port.fifosize = vendor->fifosize; | 1395 | uap->port.fifosize = uap->fifosize; |
789 | uap->port.ops = &amba_pl011_pops; | 1396 | uap->port.ops = &amba_pl011_pops; |
790 | uap->port.flags = UPF_BOOT_AUTOCONF; | 1397 | uap->port.flags = UPF_BOOT_AUTOCONF; |
791 | uap->port.line = i; | 1398 | uap->port.line = i; |
1399 | pl011_dma_probe(uap); | ||
1400 | |||
1401 | snprintf(uap->type, sizeof(uap->type), "PL011 rev%u", amba_rev(dev)); | ||
792 | 1402 | ||
793 | amba_ports[i] = uap; | 1403 | amba_ports[i] = uap; |
794 | 1404 | ||
@@ -797,6 +1407,7 @@ static int pl011_probe(struct amba_device *dev, struct amba_id *id) | |||
797 | if (ret) { | 1407 | if (ret) { |
798 | amba_set_drvdata(dev, NULL); | 1408 | amba_set_drvdata(dev, NULL); |
799 | amba_ports[i] = NULL; | 1409 | amba_ports[i] = NULL; |
1410 | pl011_dma_remove(uap); | ||
800 | clk_put(uap->clk); | 1411 | clk_put(uap->clk); |
801 | unmap: | 1412 | unmap: |
802 | iounmap(base); | 1413 | iounmap(base); |
@@ -820,13 +1431,36 @@ static int pl011_remove(struct amba_device *dev) | |||
820 | if (amba_ports[i] == uap) | 1431 | if (amba_ports[i] == uap) |
821 | amba_ports[i] = NULL; | 1432 | amba_ports[i] = NULL; |
822 | 1433 | ||
1434 | pl011_dma_remove(uap); | ||
823 | iounmap(uap->port.membase); | 1435 | iounmap(uap->port.membase); |
824 | clk_put(uap->clk); | 1436 | clk_put(uap->clk); |
825 | kfree(uap); | 1437 | kfree(uap); |
826 | return 0; | 1438 | return 0; |
827 | } | 1439 | } |
828 | 1440 | ||
829 | static struct amba_id pl011_ids[] __initdata = { | 1441 | #ifdef CONFIG_PM |
1442 | static int pl011_suspend(struct amba_device *dev, pm_message_t state) | ||
1443 | { | ||
1444 | struct uart_amba_port *uap = amba_get_drvdata(dev); | ||
1445 | |||
1446 | if (!uap) | ||
1447 | return -EINVAL; | ||
1448 | |||
1449 | return uart_suspend_port(&amba_reg, &uap->port); | ||
1450 | } | ||
1451 | |||
1452 | static int pl011_resume(struct amba_device *dev) | ||
1453 | { | ||
1454 | struct uart_amba_port *uap = amba_get_drvdata(dev); | ||
1455 | |||
1456 | if (!uap) | ||
1457 | return -EINVAL; | ||
1458 | |||
1459 | return uart_resume_port(&amba_reg, &uap->port); | ||
1460 | } | ||
1461 | #endif | ||
1462 | |||
1463 | static struct amba_id pl011_ids[] = { | ||
830 | { | 1464 | { |
831 | .id = 0x00041011, | 1465 | .id = 0x00041011, |
832 | .mask = 0x000fffff, | 1466 | .mask = 0x000fffff, |
@@ -847,6 +1481,10 @@ static struct amba_driver pl011_driver = { | |||
847 | .id_table = pl011_ids, | 1481 | .id_table = pl011_ids, |
848 | .probe = pl011_probe, | 1482 | .probe = pl011_probe, |
849 | .remove = pl011_remove, | 1483 | .remove = pl011_remove, |
1484 | #ifdef CONFIG_PM | ||
1485 | .suspend = pl011_suspend, | ||
1486 | .resume = pl011_resume, | ||
1487 | #endif | ||
850 | }; | 1488 | }; |
851 | 1489 | ||
852 | static int __init pl011_init(void) | 1490 | static int __init pl011_init(void) |
diff --git a/drivers/serial/apbuart.c b/drivers/serial/apbuart.c new file mode 100644 index 000000000000..095a5d562618 --- /dev/null +++ b/drivers/serial/apbuart.c | |||
@@ -0,0 +1,709 @@ | |||
1 | /* | ||
2 | * Driver for GRLIB serial ports (APBUART) | ||
3 | * | ||
4 | * Based on linux/drivers/serial/amba.c | ||
5 | * | ||
6 | * Copyright (C) 2000 Deep Blue Solutions Ltd. | ||
7 | * Copyright (C) 2003 Konrad Eisele <eiselekd@web.de> | ||
8 | * Copyright (C) 2006 Daniel Hellstrom <daniel@gaisler.com>, Aeroflex Gaisler AB | ||
9 | * Copyright (C) 2008 Gilead Kutnick <kutnickg@zin-tech.com> | ||
10 | * Copyright (C) 2009 Kristoffer Glembo <kristoffer@gaisler.com>, Aeroflex Gaisler AB | ||
11 | */ | ||
12 | |||
13 | #if defined(CONFIG_SERIAL_GRLIB_GAISLER_APBUART_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | ||
14 | #define SUPPORT_SYSRQ | ||
15 | #endif | ||
16 | |||
17 | #include <linux/module.h> | ||
18 | #include <linux/tty.h> | ||
19 | #include <linux/ioport.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/serial.h> | ||
22 | #include <linux/console.h> | ||
23 | #include <linux/sysrq.h> | ||
24 | #include <linux/kthread.h> | ||
25 | #include <linux/device.h> | ||
26 | #include <linux/of.h> | ||
27 | #include <linux/of_device.h> | ||
28 | #include <linux/of_platform.h> | ||
29 | #include <linux/of_irq.h> | ||
30 | #include <linux/platform_device.h> | ||
31 | #include <linux/io.h> | ||
32 | #include <linux/serial_core.h> | ||
33 | #include <asm/irq.h> | ||
34 | |||
35 | #include "apbuart.h" | ||
36 | |||
37 | #define SERIAL_APBUART_MAJOR TTY_MAJOR | ||
38 | #define SERIAL_APBUART_MINOR 64 | ||
39 | #define UART_DUMMY_RSR_RX 0x8000 /* for ignore all read */ | ||
40 | |||
41 | static void apbuart_tx_chars(struct uart_port *port); | ||
42 | |||
43 | static void apbuart_stop_tx(struct uart_port *port) | ||
44 | { | ||
45 | unsigned int cr; | ||
46 | |||
47 | cr = UART_GET_CTRL(port); | ||
48 | cr &= ~UART_CTRL_TI; | ||
49 | UART_PUT_CTRL(port, cr); | ||
50 | } | ||
51 | |||
52 | static void apbuart_start_tx(struct uart_port *port) | ||
53 | { | ||
54 | unsigned int cr; | ||
55 | |||
56 | cr = UART_GET_CTRL(port); | ||
57 | cr |= UART_CTRL_TI; | ||
58 | UART_PUT_CTRL(port, cr); | ||
59 | |||
60 | if (UART_GET_STATUS(port) & UART_STATUS_THE) | ||
61 | apbuart_tx_chars(port); | ||
62 | } | ||
63 | |||
64 | static void apbuart_stop_rx(struct uart_port *port) | ||
65 | { | ||
66 | unsigned int cr; | ||
67 | |||
68 | cr = UART_GET_CTRL(port); | ||
69 | cr &= ~(UART_CTRL_RI); | ||
70 | UART_PUT_CTRL(port, cr); | ||
71 | } | ||
72 | |||
73 | static void apbuart_enable_ms(struct uart_port *port) | ||
74 | { | ||
75 | /* No modem status change interrupts for APBUART */ | ||
76 | } | ||
77 | |||
78 | static void apbuart_rx_chars(struct uart_port *port) | ||
79 | { | ||
80 | struct tty_struct *tty = port->state->port.tty; | ||
81 | unsigned int status, ch, rsr, flag; | ||
82 | unsigned int max_chars = port->fifosize; | ||
83 | |||
84 | status = UART_GET_STATUS(port); | ||
85 | |||
86 | while (UART_RX_DATA(status) && (max_chars--)) { | ||
87 | |||
88 | ch = UART_GET_CHAR(port); | ||
89 | flag = TTY_NORMAL; | ||
90 | |||
91 | port->icount.rx++; | ||
92 | |||
93 | rsr = UART_GET_STATUS(port) | UART_DUMMY_RSR_RX; | ||
94 | UART_PUT_STATUS(port, 0); | ||
95 | if (rsr & UART_STATUS_ERR) { | ||
96 | |||
97 | if (rsr & UART_STATUS_BR) { | ||
98 | rsr &= ~(UART_STATUS_FE | UART_STATUS_PE); | ||
99 | port->icount.brk++; | ||
100 | if (uart_handle_break(port)) | ||
101 | goto ignore_char; | ||
102 | } else if (rsr & UART_STATUS_PE) { | ||
103 | port->icount.parity++; | ||
104 | } else if (rsr & UART_STATUS_FE) { | ||
105 | port->icount.frame++; | ||
106 | } | ||
107 | if (rsr & UART_STATUS_OE) | ||
108 | port->icount.overrun++; | ||
109 | |||
110 | rsr &= port->read_status_mask; | ||
111 | |||
112 | if (rsr & UART_STATUS_PE) | ||
113 | flag = TTY_PARITY; | ||
114 | else if (rsr & UART_STATUS_FE) | ||
115 | flag = TTY_FRAME; | ||
116 | } | ||
117 | |||
118 | if (uart_handle_sysrq_char(port, ch)) | ||
119 | goto ignore_char; | ||
120 | |||
121 | uart_insert_char(port, rsr, UART_STATUS_OE, ch, flag); | ||
122 | |||
123 | |||
124 | ignore_char: | ||
125 | status = UART_GET_STATUS(port); | ||
126 | } | ||
127 | |||
128 | tty_flip_buffer_push(tty); | ||
129 | } | ||
130 | |||
131 | static void apbuart_tx_chars(struct uart_port *port) | ||
132 | { | ||
133 | struct circ_buf *xmit = &port->state->xmit; | ||
134 | int count; | ||
135 | |||
136 | if (port->x_char) { | ||
137 | UART_PUT_CHAR(port, port->x_char); | ||
138 | port->icount.tx++; | ||
139 | port->x_char = 0; | ||
140 | return; | ||
141 | } | ||
142 | |||
143 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { | ||
144 | apbuart_stop_tx(port); | ||
145 | return; | ||
146 | } | ||
147 | |||
148 | /* amba: fill FIFO */ | ||
149 | count = port->fifosize >> 1; | ||
150 | do { | ||
151 | UART_PUT_CHAR(port, xmit->buf[xmit->tail]); | ||
152 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
153 | port->icount.tx++; | ||
154 | if (uart_circ_empty(xmit)) | ||
155 | break; | ||
156 | } while (--count > 0); | ||
157 | |||
158 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
159 | uart_write_wakeup(port); | ||
160 | |||
161 | if (uart_circ_empty(xmit)) | ||
162 | apbuart_stop_tx(port); | ||
163 | } | ||
164 | |||
165 | static irqreturn_t apbuart_int(int irq, void *dev_id) | ||
166 | { | ||
167 | struct uart_port *port = dev_id; | ||
168 | unsigned int status; | ||
169 | |||
170 | spin_lock(&port->lock); | ||
171 | |||
172 | status = UART_GET_STATUS(port); | ||
173 | if (status & UART_STATUS_DR) | ||
174 | apbuart_rx_chars(port); | ||
175 | if (status & UART_STATUS_THE) | ||
176 | apbuart_tx_chars(port); | ||
177 | |||
178 | spin_unlock(&port->lock); | ||
179 | |||
180 | return IRQ_HANDLED; | ||
181 | } | ||
182 | |||
183 | static unsigned int apbuart_tx_empty(struct uart_port *port) | ||
184 | { | ||
185 | unsigned int status = UART_GET_STATUS(port); | ||
186 | return status & UART_STATUS_THE ? TIOCSER_TEMT : 0; | ||
187 | } | ||
188 | |||
189 | static unsigned int apbuart_get_mctrl(struct uart_port *port) | ||
190 | { | ||
191 | /* The GRLIB APBUART handles flow control in hardware */ | ||
192 | return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; | ||
193 | } | ||
194 | |||
195 | static void apbuart_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
196 | { | ||
197 | /* The GRLIB APBUART handles flow control in hardware */ | ||
198 | } | ||
199 | |||
200 | static void apbuart_break_ctl(struct uart_port *port, int break_state) | ||
201 | { | ||
202 | /* We don't support sending break */ | ||
203 | } | ||
204 | |||
205 | static int apbuart_startup(struct uart_port *port) | ||
206 | { | ||
207 | int retval; | ||
208 | unsigned int cr; | ||
209 | |||
210 | /* Allocate the IRQ */ | ||
211 | retval = request_irq(port->irq, apbuart_int, 0, "apbuart", port); | ||
212 | if (retval) | ||
213 | return retval; | ||
214 | |||
215 | /* Finally, enable interrupts */ | ||
216 | cr = UART_GET_CTRL(port); | ||
217 | UART_PUT_CTRL(port, | ||
218 | cr | UART_CTRL_RE | UART_CTRL_TE | | ||
219 | UART_CTRL_RI | UART_CTRL_TI); | ||
220 | |||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | static void apbuart_shutdown(struct uart_port *port) | ||
225 | { | ||
226 | unsigned int cr; | ||
227 | |||
228 | /* disable all interrupts, disable the port */ | ||
229 | cr = UART_GET_CTRL(port); | ||
230 | UART_PUT_CTRL(port, | ||
231 | cr & ~(UART_CTRL_RE | UART_CTRL_TE | | ||
232 | UART_CTRL_RI | UART_CTRL_TI)); | ||
233 | |||
234 | /* Free the interrupt */ | ||
235 | free_irq(port->irq, port); | ||
236 | } | ||
237 | |||
238 | static void apbuart_set_termios(struct uart_port *port, | ||
239 | struct ktermios *termios, struct ktermios *old) | ||
240 | { | ||
241 | unsigned int cr; | ||
242 | unsigned long flags; | ||
243 | unsigned int baud, quot; | ||
244 | |||
245 | /* Ask the core to calculate the divisor for us. */ | ||
246 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); | ||
247 | if (baud == 0) | ||
248 | panic("invalid baudrate %i\n", port->uartclk / 16); | ||
249 | |||
250 | /* uart_get_divisor calc a *16 uart freq, apbuart is *8 */ | ||
251 | quot = (uart_get_divisor(port, baud)) * 2; | ||
252 | cr = UART_GET_CTRL(port); | ||
253 | cr &= ~(UART_CTRL_PE | UART_CTRL_PS); | ||
254 | |||
255 | if (termios->c_cflag & PARENB) { | ||
256 | cr |= UART_CTRL_PE; | ||
257 | if ((termios->c_cflag & PARODD)) | ||
258 | cr |= UART_CTRL_PS; | ||
259 | } | ||
260 | |||
261 | /* Enable flow control. */ | ||
262 | if (termios->c_cflag & CRTSCTS) | ||
263 | cr |= UART_CTRL_FL; | ||
264 | |||
265 | spin_lock_irqsave(&port->lock, flags); | ||
266 | |||
267 | /* Update the per-port timeout. */ | ||
268 | uart_update_timeout(port, termios->c_cflag, baud); | ||
269 | |||
270 | port->read_status_mask = UART_STATUS_OE; | ||
271 | if (termios->c_iflag & INPCK) | ||
272 | port->read_status_mask |= UART_STATUS_FE | UART_STATUS_PE; | ||
273 | |||
274 | /* Characters to ignore */ | ||
275 | port->ignore_status_mask = 0; | ||
276 | if (termios->c_iflag & IGNPAR) | ||
277 | port->ignore_status_mask |= UART_STATUS_FE | UART_STATUS_PE; | ||
278 | |||
279 | /* Ignore all characters if CREAD is not set. */ | ||
280 | if ((termios->c_cflag & CREAD) == 0) | ||
281 | port->ignore_status_mask |= UART_DUMMY_RSR_RX; | ||
282 | |||
283 | /* Set baud rate */ | ||
284 | quot -= 1; | ||
285 | UART_PUT_SCAL(port, quot); | ||
286 | UART_PUT_CTRL(port, cr); | ||
287 | |||
288 | spin_unlock_irqrestore(&port->lock, flags); | ||
289 | } | ||
290 | |||
291 | static const char *apbuart_type(struct uart_port *port) | ||
292 | { | ||
293 | return port->type == PORT_APBUART ? "GRLIB/APBUART" : NULL; | ||
294 | } | ||
295 | |||
296 | static void apbuart_release_port(struct uart_port *port) | ||
297 | { | ||
298 | release_mem_region(port->mapbase, 0x100); | ||
299 | } | ||
300 | |||
301 | static int apbuart_request_port(struct uart_port *port) | ||
302 | { | ||
303 | return request_mem_region(port->mapbase, 0x100, "grlib-apbuart") | ||
304 | != NULL ? 0 : -EBUSY; | ||
305 | return 0; | ||
306 | } | ||
307 | |||
308 | /* Configure/autoconfigure the port */ | ||
309 | static void apbuart_config_port(struct uart_port *port, int flags) | ||
310 | { | ||
311 | if (flags & UART_CONFIG_TYPE) { | ||
312 | port->type = PORT_APBUART; | ||
313 | apbuart_request_port(port); | ||
314 | } | ||
315 | } | ||
316 | |||
317 | /* Verify the new serial_struct (for TIOCSSERIAL) */ | ||
318 | static int apbuart_verify_port(struct uart_port *port, | ||
319 | struct serial_struct *ser) | ||
320 | { | ||
321 | int ret = 0; | ||
322 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_APBUART) | ||
323 | ret = -EINVAL; | ||
324 | if (ser->irq < 0 || ser->irq >= NR_IRQS) | ||
325 | ret = -EINVAL; | ||
326 | if (ser->baud_base < 9600) | ||
327 | ret = -EINVAL; | ||
328 | return ret; | ||
329 | } | ||
330 | |||
331 | static struct uart_ops grlib_apbuart_ops = { | ||
332 | .tx_empty = apbuart_tx_empty, | ||
333 | .set_mctrl = apbuart_set_mctrl, | ||
334 | .get_mctrl = apbuart_get_mctrl, | ||
335 | .stop_tx = apbuart_stop_tx, | ||
336 | .start_tx = apbuart_start_tx, | ||
337 | .stop_rx = apbuart_stop_rx, | ||
338 | .enable_ms = apbuart_enable_ms, | ||
339 | .break_ctl = apbuart_break_ctl, | ||
340 | .startup = apbuart_startup, | ||
341 | .shutdown = apbuart_shutdown, | ||
342 | .set_termios = apbuart_set_termios, | ||
343 | .type = apbuart_type, | ||
344 | .release_port = apbuart_release_port, | ||
345 | .request_port = apbuart_request_port, | ||
346 | .config_port = apbuart_config_port, | ||
347 | .verify_port = apbuart_verify_port, | ||
348 | }; | ||
349 | |||
350 | static struct uart_port grlib_apbuart_ports[UART_NR]; | ||
351 | static struct device_node *grlib_apbuart_nodes[UART_NR]; | ||
352 | |||
353 | static int apbuart_scan_fifo_size(struct uart_port *port, int portnumber) | ||
354 | { | ||
355 | int ctrl, loop = 0; | ||
356 | int status; | ||
357 | int fifosize; | ||
358 | unsigned long flags; | ||
359 | |||
360 | ctrl = UART_GET_CTRL(port); | ||
361 | |||
362 | /* | ||
363 | * Enable the transceiver and wait for it to be ready to send data. | ||
364 | * Clear interrupts so that this process will not be externally | ||
365 | * interrupted in the middle (which can cause the transceiver to | ||
366 | * drain prematurely). | ||
367 | */ | ||
368 | |||
369 | local_irq_save(flags); | ||
370 | |||
371 | UART_PUT_CTRL(port, ctrl | UART_CTRL_TE); | ||
372 | |||
373 | while (!UART_TX_READY(UART_GET_STATUS(port))) | ||
374 | loop++; | ||
375 | |||
376 | /* | ||
377 | * Disable the transceiver so data isn't actually sent during the | ||
378 | * actual test. | ||
379 | */ | ||
380 | |||
381 | UART_PUT_CTRL(port, ctrl & ~(UART_CTRL_TE)); | ||
382 | |||
383 | fifosize = 1; | ||
384 | UART_PUT_CHAR(port, 0); | ||
385 | |||
386 | /* | ||
387 | * So long as transmitting a character increments the tranceivier FIFO | ||
388 | * length the FIFO must be at least that big. These bytes will | ||
389 | * automatically drain off of the FIFO. | ||
390 | */ | ||
391 | |||
392 | status = UART_GET_STATUS(port); | ||
393 | while (((status >> 20) & 0x3F) == fifosize) { | ||
394 | fifosize++; | ||
395 | UART_PUT_CHAR(port, 0); | ||
396 | status = UART_GET_STATUS(port); | ||
397 | } | ||
398 | |||
399 | fifosize--; | ||
400 | |||
401 | UART_PUT_CTRL(port, ctrl); | ||
402 | local_irq_restore(flags); | ||
403 | |||
404 | if (fifosize == 0) | ||
405 | fifosize = 1; | ||
406 | |||
407 | return fifosize; | ||
408 | } | ||
409 | |||
410 | static void apbuart_flush_fifo(struct uart_port *port) | ||
411 | { | ||
412 | int i; | ||
413 | |||
414 | for (i = 0; i < port->fifosize; i++) | ||
415 | UART_GET_CHAR(port); | ||
416 | } | ||
417 | |||
418 | |||
419 | /* ======================================================================== */ | ||
420 | /* Console driver, if enabled */ | ||
421 | /* ======================================================================== */ | ||
422 | |||
423 | #ifdef CONFIG_SERIAL_GRLIB_GAISLER_APBUART_CONSOLE | ||
424 | |||
425 | static void apbuart_console_putchar(struct uart_port *port, int ch) | ||
426 | { | ||
427 | unsigned int status; | ||
428 | do { | ||
429 | status = UART_GET_STATUS(port); | ||
430 | } while (!UART_TX_READY(status)); | ||
431 | UART_PUT_CHAR(port, ch); | ||
432 | } | ||
433 | |||
434 | static void | ||
435 | apbuart_console_write(struct console *co, const char *s, unsigned int count) | ||
436 | { | ||
437 | struct uart_port *port = &grlib_apbuart_ports[co->index]; | ||
438 | unsigned int status, old_cr, new_cr; | ||
439 | |||
440 | /* First save the CR then disable the interrupts */ | ||
441 | old_cr = UART_GET_CTRL(port); | ||
442 | new_cr = old_cr & ~(UART_CTRL_RI | UART_CTRL_TI); | ||
443 | UART_PUT_CTRL(port, new_cr); | ||
444 | |||
445 | uart_console_write(port, s, count, apbuart_console_putchar); | ||
446 | |||
447 | /* | ||
448 | * Finally, wait for transmitter to become empty | ||
449 | * and restore the TCR | ||
450 | */ | ||
451 | do { | ||
452 | status = UART_GET_STATUS(port); | ||
453 | } while (!UART_TX_READY(status)); | ||
454 | UART_PUT_CTRL(port, old_cr); | ||
455 | } | ||
456 | |||
457 | static void __init | ||
458 | apbuart_console_get_options(struct uart_port *port, int *baud, | ||
459 | int *parity, int *bits) | ||
460 | { | ||
461 | if (UART_GET_CTRL(port) & (UART_CTRL_RE | UART_CTRL_TE)) { | ||
462 | |||
463 | unsigned int quot, status; | ||
464 | status = UART_GET_STATUS(port); | ||
465 | |||
466 | *parity = 'n'; | ||
467 | if (status & UART_CTRL_PE) { | ||
468 | if ((status & UART_CTRL_PS) == 0) | ||
469 | *parity = 'e'; | ||
470 | else | ||
471 | *parity = 'o'; | ||
472 | } | ||
473 | |||
474 | *bits = 8; | ||
475 | quot = UART_GET_SCAL(port) / 8; | ||
476 | *baud = port->uartclk / (16 * (quot + 1)); | ||
477 | } | ||
478 | } | ||
479 | |||
480 | static int __init apbuart_console_setup(struct console *co, char *options) | ||
481 | { | ||
482 | struct uart_port *port; | ||
483 | int baud = 38400; | ||
484 | int bits = 8; | ||
485 | int parity = 'n'; | ||
486 | int flow = 'n'; | ||
487 | |||
488 | pr_debug("apbuart_console_setup co=%p, co->index=%i, options=%s\n", | ||
489 | co, co->index, options); | ||
490 | |||
491 | /* | ||
492 | * Check whether an invalid uart number has been specified, and | ||
493 | * if so, search for the first available port that does have | ||
494 | * console support. | ||
495 | */ | ||
496 | if (co->index >= grlib_apbuart_port_nr) | ||
497 | co->index = 0; | ||
498 | |||
499 | port = &grlib_apbuart_ports[co->index]; | ||
500 | |||
501 | spin_lock_init(&port->lock); | ||
502 | |||
503 | if (options) | ||
504 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
505 | else | ||
506 | apbuart_console_get_options(port, &baud, &parity, &bits); | ||
507 | |||
508 | return uart_set_options(port, co, baud, parity, bits, flow); | ||
509 | } | ||
510 | |||
511 | static struct uart_driver grlib_apbuart_driver; | ||
512 | |||
513 | static struct console grlib_apbuart_console = { | ||
514 | .name = "ttyS", | ||
515 | .write = apbuart_console_write, | ||
516 | .device = uart_console_device, | ||
517 | .setup = apbuart_console_setup, | ||
518 | .flags = CON_PRINTBUFFER, | ||
519 | .index = -1, | ||
520 | .data = &grlib_apbuart_driver, | ||
521 | }; | ||
522 | |||
523 | |||
524 | static int grlib_apbuart_configure(void); | ||
525 | |||
526 | static int __init apbuart_console_init(void) | ||
527 | { | ||
528 | if (grlib_apbuart_configure()) | ||
529 | return -ENODEV; | ||
530 | register_console(&grlib_apbuart_console); | ||
531 | return 0; | ||
532 | } | ||
533 | |||
534 | console_initcall(apbuart_console_init); | ||
535 | |||
536 | #define APBUART_CONSOLE (&grlib_apbuart_console) | ||
537 | #else | ||
538 | #define APBUART_CONSOLE NULL | ||
539 | #endif | ||
540 | |||
541 | static struct uart_driver grlib_apbuart_driver = { | ||
542 | .owner = THIS_MODULE, | ||
543 | .driver_name = "serial", | ||
544 | .dev_name = "ttyS", | ||
545 | .major = SERIAL_APBUART_MAJOR, | ||
546 | .minor = SERIAL_APBUART_MINOR, | ||
547 | .nr = UART_NR, | ||
548 | .cons = APBUART_CONSOLE, | ||
549 | }; | ||
550 | |||
551 | |||
552 | /* ======================================================================== */ | ||
553 | /* OF Platform Driver */ | ||
554 | /* ======================================================================== */ | ||
555 | |||
556 | static int __devinit apbuart_probe(struct platform_device *op, | ||
557 | const struct of_device_id *match) | ||
558 | { | ||
559 | int i = -1; | ||
560 | struct uart_port *port = NULL; | ||
561 | |||
562 | i = 0; | ||
563 | for (i = 0; i < grlib_apbuart_port_nr; i++) { | ||
564 | if (op->dev.of_node == grlib_apbuart_nodes[i]) | ||
565 | break; | ||
566 | } | ||
567 | |||
568 | port = &grlib_apbuart_ports[i]; | ||
569 | port->dev = &op->dev; | ||
570 | |||
571 | uart_add_one_port(&grlib_apbuart_driver, (struct uart_port *) port); | ||
572 | |||
573 | apbuart_flush_fifo((struct uart_port *) port); | ||
574 | |||
575 | printk(KERN_INFO "grlib-apbuart at 0x%llx, irq %d\n", | ||
576 | (unsigned long long) port->mapbase, port->irq); | ||
577 | return 0; | ||
578 | } | ||
579 | |||
580 | static struct of_device_id __initdata apbuart_match[] = { | ||
581 | { | ||
582 | .name = "GAISLER_APBUART", | ||
583 | }, | ||
584 | { | ||
585 | .name = "01_00c", | ||
586 | }, | ||
587 | {}, | ||
588 | }; | ||
589 | |||
590 | static struct of_platform_driver grlib_apbuart_of_driver = { | ||
591 | .probe = apbuart_probe, | ||
592 | .driver = { | ||
593 | .owner = THIS_MODULE, | ||
594 | .name = "grlib-apbuart", | ||
595 | .of_match_table = apbuart_match, | ||
596 | }, | ||
597 | }; | ||
598 | |||
599 | |||
600 | static int grlib_apbuart_configure(void) | ||
601 | { | ||
602 | struct device_node *np, *rp; | ||
603 | const u32 *prop; | ||
604 | int freq_khz, line = 0; | ||
605 | |||
606 | /* Get bus frequency */ | ||
607 | rp = of_find_node_by_path("/"); | ||
608 | if (!rp) | ||
609 | return -ENODEV; | ||
610 | rp = of_get_next_child(rp, NULL); | ||
611 | if (!rp) | ||
612 | return -ENODEV; | ||
613 | prop = of_get_property(rp, "clock-frequency", NULL); | ||
614 | if (!prop) | ||
615 | return -ENODEV; | ||
616 | freq_khz = *prop; | ||
617 | |||
618 | for_each_matching_node(np, apbuart_match) { | ||
619 | const int *irqs, *ampopts; | ||
620 | const struct amba_prom_registers *regs; | ||
621 | struct uart_port *port; | ||
622 | unsigned long addr; | ||
623 | |||
624 | ampopts = of_get_property(np, "ampopts", NULL); | ||
625 | if (ampopts && (*ampopts == 0)) | ||
626 | continue; /* Ignore if used by another OS instance */ | ||
627 | |||
628 | irqs = of_get_property(np, "interrupts", NULL); | ||
629 | regs = of_get_property(np, "reg", NULL); | ||
630 | |||
631 | if (!irqs || !regs) | ||
632 | continue; | ||
633 | |||
634 | grlib_apbuart_nodes[line] = np; | ||
635 | |||
636 | addr = regs->phys_addr; | ||
637 | |||
638 | port = &grlib_apbuart_ports[line]; | ||
639 | |||
640 | port->mapbase = addr; | ||
641 | port->membase = ioremap(addr, sizeof(struct grlib_apbuart_regs_map)); | ||
642 | port->irq = *irqs; | ||
643 | port->iotype = UPIO_MEM; | ||
644 | port->ops = &grlib_apbuart_ops; | ||
645 | port->flags = UPF_BOOT_AUTOCONF; | ||
646 | port->line = line; | ||
647 | port->uartclk = freq_khz * 1000; | ||
648 | port->fifosize = apbuart_scan_fifo_size((struct uart_port *) port, line); | ||
649 | line++; | ||
650 | |||
651 | /* We support maximum UART_NR uarts ... */ | ||
652 | if (line == UART_NR) | ||
653 | break; | ||
654 | } | ||
655 | |||
656 | grlib_apbuart_driver.nr = grlib_apbuart_port_nr = line; | ||
657 | return line ? 0 : -ENODEV; | ||
658 | } | ||
659 | |||
660 | static int __init grlib_apbuart_init(void) | ||
661 | { | ||
662 | int ret; | ||
663 | |||
664 | /* Find all APBUARTS in device the tree and initialize their ports */ | ||
665 | ret = grlib_apbuart_configure(); | ||
666 | if (ret) | ||
667 | return ret; | ||
668 | |||
669 | printk(KERN_INFO "Serial: GRLIB APBUART driver\n"); | ||
670 | |||
671 | ret = uart_register_driver(&grlib_apbuart_driver); | ||
672 | |||
673 | if (ret) { | ||
674 | printk(KERN_ERR "%s: uart_register_driver failed (%i)\n", | ||
675 | __FILE__, ret); | ||
676 | return ret; | ||
677 | } | ||
678 | |||
679 | ret = of_register_platform_driver(&grlib_apbuart_of_driver); | ||
680 | if (ret) { | ||
681 | printk(KERN_ERR | ||
682 | "%s: of_register_platform_driver failed (%i)\n", | ||
683 | __FILE__, ret); | ||
684 | uart_unregister_driver(&grlib_apbuart_driver); | ||
685 | return ret; | ||
686 | } | ||
687 | |||
688 | return ret; | ||
689 | } | ||
690 | |||
691 | static void __exit grlib_apbuart_exit(void) | ||
692 | { | ||
693 | int i; | ||
694 | |||
695 | for (i = 0; i < grlib_apbuart_port_nr; i++) | ||
696 | uart_remove_one_port(&grlib_apbuart_driver, | ||
697 | &grlib_apbuart_ports[i]); | ||
698 | |||
699 | uart_unregister_driver(&grlib_apbuart_driver); | ||
700 | of_unregister_platform_driver(&grlib_apbuart_of_driver); | ||
701 | } | ||
702 | |||
703 | module_init(grlib_apbuart_init); | ||
704 | module_exit(grlib_apbuart_exit); | ||
705 | |||
706 | MODULE_AUTHOR("Aeroflex Gaisler AB"); | ||
707 | MODULE_DESCRIPTION("GRLIB APBUART serial driver"); | ||
708 | MODULE_VERSION("2.1"); | ||
709 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/serial/apbuart.h b/drivers/serial/apbuart.h new file mode 100644 index 000000000000..5faf87c8d2bc --- /dev/null +++ b/drivers/serial/apbuart.h | |||
@@ -0,0 +1,64 @@ | |||
1 | #ifndef __GRLIB_APBUART_H__ | ||
2 | #define __GRLIB_APBUART_H__ | ||
3 | |||
4 | #include <asm/io.h> | ||
5 | |||
6 | #define UART_NR 8 | ||
7 | static int grlib_apbuart_port_nr; | ||
8 | |||
9 | struct grlib_apbuart_regs_map { | ||
10 | u32 data; | ||
11 | u32 status; | ||
12 | u32 ctrl; | ||
13 | u32 scaler; | ||
14 | }; | ||
15 | |||
16 | struct amba_prom_registers { | ||
17 | unsigned int phys_addr; | ||
18 | unsigned int reg_size; | ||
19 | }; | ||
20 | |||
21 | /* | ||
22 | * The following defines the bits in the APBUART Status Registers. | ||
23 | */ | ||
24 | #define UART_STATUS_DR 0x00000001 /* Data Ready */ | ||
25 | #define UART_STATUS_TSE 0x00000002 /* TX Send Register Empty */ | ||
26 | #define UART_STATUS_THE 0x00000004 /* TX Hold Register Empty */ | ||
27 | #define UART_STATUS_BR 0x00000008 /* Break Error */ | ||
28 | #define UART_STATUS_OE 0x00000010 /* RX Overrun Error */ | ||
29 | #define UART_STATUS_PE 0x00000020 /* RX Parity Error */ | ||
30 | #define UART_STATUS_FE 0x00000040 /* RX Framing Error */ | ||
31 | #define UART_STATUS_ERR 0x00000078 /* Error Mask */ | ||
32 | |||
33 | /* | ||
34 | * The following defines the bits in the APBUART Ctrl Registers. | ||
35 | */ | ||
36 | #define UART_CTRL_RE 0x00000001 /* Receiver enable */ | ||
37 | #define UART_CTRL_TE 0x00000002 /* Transmitter enable */ | ||
38 | #define UART_CTRL_RI 0x00000004 /* Receiver interrupt enable */ | ||
39 | #define UART_CTRL_TI 0x00000008 /* Transmitter irq */ | ||
40 | #define UART_CTRL_PS 0x00000010 /* Parity select */ | ||
41 | #define UART_CTRL_PE 0x00000020 /* Parity enable */ | ||
42 | #define UART_CTRL_FL 0x00000040 /* Flow control enable */ | ||
43 | #define UART_CTRL_LB 0x00000080 /* Loopback enable */ | ||
44 | |||
45 | #define APBBASE(port) ((struct grlib_apbuart_regs_map *)((port)->membase)) | ||
46 | |||
47 | #define APBBASE_DATA_P(port) (&(APBBASE(port)->data)) | ||
48 | #define APBBASE_STATUS_P(port) (&(APBBASE(port)->status)) | ||
49 | #define APBBASE_CTRL_P(port) (&(APBBASE(port)->ctrl)) | ||
50 | #define APBBASE_SCALAR_P(port) (&(APBBASE(port)->scaler)) | ||
51 | |||
52 | #define UART_GET_CHAR(port) (__raw_readl(APBBASE_DATA_P(port))) | ||
53 | #define UART_PUT_CHAR(port, v) (__raw_writel(v, APBBASE_DATA_P(port))) | ||
54 | #define UART_GET_STATUS(port) (__raw_readl(APBBASE_STATUS_P(port))) | ||
55 | #define UART_PUT_STATUS(port, v)(__raw_writel(v, APBBASE_STATUS_P(port))) | ||
56 | #define UART_GET_CTRL(port) (__raw_readl(APBBASE_CTRL_P(port))) | ||
57 | #define UART_PUT_CTRL(port, v) (__raw_writel(v, APBBASE_CTRL_P(port))) | ||
58 | #define UART_GET_SCAL(port) (__raw_readl(APBBASE_SCALAR_P(port))) | ||
59 | #define UART_PUT_SCAL(port, v) (__raw_writel(v, APBBASE_SCALAR_P(port))) | ||
60 | |||
61 | #define UART_RX_DATA(s) (((s) & UART_STATUS_DR) != 0) | ||
62 | #define UART_TX_READY(s) (((s) & UART_STATUS_THE) != 0) | ||
63 | |||
64 | #endif /* __GRLIB_APBUART_H__ */ | ||
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c index 338b15c0a548..3892666b5fbd 100644 --- a/drivers/serial/atmel_serial.c +++ b/drivers/serial/atmel_serial.c | |||
@@ -38,8 +38,10 @@ | |||
38 | #include <linux/dma-mapping.h> | 38 | #include <linux/dma-mapping.h> |
39 | #include <linux/atmel_pdc.h> | 39 | #include <linux/atmel_pdc.h> |
40 | #include <linux/atmel_serial.h> | 40 | #include <linux/atmel_serial.h> |
41 | #include <linux/uaccess.h> | ||
41 | 42 | ||
42 | #include <asm/io.h> | 43 | #include <asm/io.h> |
44 | #include <asm/ioctls.h> | ||
43 | 45 | ||
44 | #include <asm/mach/serial_at91.h> | 46 | #include <asm/mach/serial_at91.h> |
45 | #include <mach/board.h> | 47 | #include <mach/board.h> |
@@ -59,6 +61,9 @@ | |||
59 | 61 | ||
60 | #include <linux/serial_core.h> | 62 | #include <linux/serial_core.h> |
61 | 63 | ||
64 | static void atmel_start_rx(struct uart_port *port); | ||
65 | static void atmel_stop_rx(struct uart_port *port); | ||
66 | |||
62 | #ifdef CONFIG_SERIAL_ATMEL_TTYAT | 67 | #ifdef CONFIG_SERIAL_ATMEL_TTYAT |
63 | 68 | ||
64 | /* Use device name ttyAT, major 204 and minor 154-169. This is necessary if we | 69 | /* Use device name ttyAT, major 204 and minor 154-169. This is necessary if we |
@@ -93,6 +98,7 @@ | |||
93 | #define UART_GET_BRGR(port) __raw_readl((port)->membase + ATMEL_US_BRGR) | 98 | #define UART_GET_BRGR(port) __raw_readl((port)->membase + ATMEL_US_BRGR) |
94 | #define UART_PUT_BRGR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_BRGR) | 99 | #define UART_PUT_BRGR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_BRGR) |
95 | #define UART_PUT_RTOR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_RTOR) | 100 | #define UART_PUT_RTOR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_RTOR) |
101 | #define UART_PUT_TTGR(port, v) __raw_writel(v, (port)->membase + ATMEL_US_TTGR) | ||
96 | 102 | ||
97 | /* PDC registers */ | 103 | /* PDC registers */ |
98 | #define UART_PUT_PTCR(port,v) __raw_writel(v, (port)->membase + ATMEL_PDC_PTCR) | 104 | #define UART_PUT_PTCR(port,v) __raw_writel(v, (port)->membase + ATMEL_PDC_PTCR) |
@@ -147,6 +153,9 @@ struct atmel_uart_port { | |||
147 | unsigned int irq_status_prev; | 153 | unsigned int irq_status_prev; |
148 | 154 | ||
149 | struct circ_buf rx_ring; | 155 | struct circ_buf rx_ring; |
156 | |||
157 | struct serial_rs485 rs485; /* rs485 settings */ | ||
158 | unsigned int tx_done_mask; | ||
150 | }; | 159 | }; |
151 | 160 | ||
152 | static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART]; | 161 | static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART]; |
@@ -187,6 +196,47 @@ static bool atmel_use_dma_tx(struct uart_port *port) | |||
187 | } | 196 | } |
188 | #endif | 197 | #endif |
189 | 198 | ||
199 | /* Enable or disable the rs485 support */ | ||
200 | void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) | ||
201 | { | ||
202 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | ||
203 | unsigned int mode; | ||
204 | |||
205 | spin_lock(&port->lock); | ||
206 | |||
207 | /* Disable interrupts */ | ||
208 | UART_PUT_IDR(port, atmel_port->tx_done_mask); | ||
209 | |||
210 | mode = UART_GET_MR(port); | ||
211 | |||
212 | /* Resetting serial mode to RS232 (0x0) */ | ||
213 | mode &= ~ATMEL_US_USMODE; | ||
214 | |||
215 | atmel_port->rs485 = *rs485conf; | ||
216 | |||
217 | if (rs485conf->flags & SER_RS485_ENABLED) { | ||
218 | dev_dbg(port->dev, "Setting UART to RS485\n"); | ||
219 | atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; | ||
220 | if (rs485conf->flags & SER_RS485_RTS_AFTER_SEND) | ||
221 | UART_PUT_TTGR(port, rs485conf->delay_rts_after_send); | ||
222 | mode |= ATMEL_US_USMODE_RS485; | ||
223 | } else { | ||
224 | dev_dbg(port->dev, "Setting UART to RS232\n"); | ||
225 | if (atmel_use_dma_tx(port)) | ||
226 | atmel_port->tx_done_mask = ATMEL_US_ENDTX | | ||
227 | ATMEL_US_TXBUFE; | ||
228 | else | ||
229 | atmel_port->tx_done_mask = ATMEL_US_TXRDY; | ||
230 | } | ||
231 | UART_PUT_MR(port, mode); | ||
232 | |||
233 | /* Enable interrupts */ | ||
234 | UART_PUT_IER(port, atmel_port->tx_done_mask); | ||
235 | |||
236 | spin_unlock(&port->lock); | ||
237 | |||
238 | } | ||
239 | |||
190 | /* | 240 | /* |
191 | * Return TIOCSER_TEMT when transmitter FIFO and Shift register is empty. | 241 | * Return TIOCSER_TEMT when transmitter FIFO and Shift register is empty. |
192 | */ | 242 | */ |
@@ -202,6 +252,7 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl) | |||
202 | { | 252 | { |
203 | unsigned int control = 0; | 253 | unsigned int control = 0; |
204 | unsigned int mode; | 254 | unsigned int mode; |
255 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | ||
205 | 256 | ||
206 | #ifdef CONFIG_ARCH_AT91RM9200 | 257 | #ifdef CONFIG_ARCH_AT91RM9200 |
207 | if (cpu_is_at91rm9200()) { | 258 | if (cpu_is_at91rm9200()) { |
@@ -236,6 +287,19 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl) | |||
236 | mode |= ATMEL_US_CHMODE_LOC_LOOP; | 287 | mode |= ATMEL_US_CHMODE_LOC_LOOP; |
237 | else | 288 | else |
238 | mode |= ATMEL_US_CHMODE_NORMAL; | 289 | mode |= ATMEL_US_CHMODE_NORMAL; |
290 | |||
291 | /* Resetting serial mode to RS232 (0x0) */ | ||
292 | mode &= ~ATMEL_US_USMODE; | ||
293 | |||
294 | if (atmel_port->rs485.flags & SER_RS485_ENABLED) { | ||
295 | dev_dbg(port->dev, "Setting UART to RS485\n"); | ||
296 | if (atmel_port->rs485.flags & SER_RS485_RTS_AFTER_SEND) | ||
297 | UART_PUT_TTGR(port, | ||
298 | atmel_port->rs485.delay_rts_after_send); | ||
299 | mode |= ATMEL_US_USMODE_RS485; | ||
300 | } else { | ||
301 | dev_dbg(port->dev, "Setting UART to RS232\n"); | ||
302 | } | ||
239 | UART_PUT_MR(port, mode); | 303 | UART_PUT_MR(port, mode); |
240 | } | 304 | } |
241 | 305 | ||
@@ -268,12 +332,17 @@ static u_int atmel_get_mctrl(struct uart_port *port) | |||
268 | */ | 332 | */ |
269 | static void atmel_stop_tx(struct uart_port *port) | 333 | static void atmel_stop_tx(struct uart_port *port) |
270 | { | 334 | { |
335 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | ||
336 | |||
271 | if (atmel_use_dma_tx(port)) { | 337 | if (atmel_use_dma_tx(port)) { |
272 | /* disable PDC transmit */ | 338 | /* disable PDC transmit */ |
273 | UART_PUT_PTCR(port, ATMEL_PDC_TXTDIS); | 339 | UART_PUT_PTCR(port, ATMEL_PDC_TXTDIS); |
274 | UART_PUT_IDR(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE); | 340 | } |
275 | } else | 341 | /* Disable interrupts */ |
276 | UART_PUT_IDR(port, ATMEL_US_TXRDY); | 342 | UART_PUT_IDR(port, atmel_port->tx_done_mask); |
343 | |||
344 | if (atmel_port->rs485.flags & SER_RS485_ENABLED) | ||
345 | atmel_start_rx(port); | ||
277 | } | 346 | } |
278 | 347 | ||
279 | /* | 348 | /* |
@@ -281,17 +350,39 @@ static void atmel_stop_tx(struct uart_port *port) | |||
281 | */ | 350 | */ |
282 | static void atmel_start_tx(struct uart_port *port) | 351 | static void atmel_start_tx(struct uart_port *port) |
283 | { | 352 | { |
353 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | ||
354 | |||
284 | if (atmel_use_dma_tx(port)) { | 355 | if (atmel_use_dma_tx(port)) { |
285 | if (UART_GET_PTSR(port) & ATMEL_PDC_TXTEN) | 356 | if (UART_GET_PTSR(port) & ATMEL_PDC_TXTEN) |
286 | /* The transmitter is already running. Yes, we | 357 | /* The transmitter is already running. Yes, we |
287 | really need this.*/ | 358 | really need this.*/ |
288 | return; | 359 | return; |
289 | 360 | ||
290 | UART_PUT_IER(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE); | 361 | if (atmel_port->rs485.flags & SER_RS485_ENABLED) |
362 | atmel_stop_rx(port); | ||
363 | |||
291 | /* re-enable PDC transmit */ | 364 | /* re-enable PDC transmit */ |
292 | UART_PUT_PTCR(port, ATMEL_PDC_TXTEN); | 365 | UART_PUT_PTCR(port, ATMEL_PDC_TXTEN); |
293 | } else | 366 | } |
294 | UART_PUT_IER(port, ATMEL_US_TXRDY); | 367 | /* Enable interrupts */ |
368 | UART_PUT_IER(port, atmel_port->tx_done_mask); | ||
369 | } | ||
370 | |||
371 | /* | ||
372 | * start receiving - port is in process of being opened. | ||
373 | */ | ||
374 | static void atmel_start_rx(struct uart_port *port) | ||
375 | { | ||
376 | UART_PUT_CR(port, ATMEL_US_RSTSTA); /* reset status and receiver */ | ||
377 | |||
378 | if (atmel_use_dma_rx(port)) { | ||
379 | /* enable PDC controller */ | ||
380 | UART_PUT_IER(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT | | ||
381 | port->read_status_mask); | ||
382 | UART_PUT_PTCR(port, ATMEL_PDC_RXTEN); | ||
383 | } else { | ||
384 | UART_PUT_IER(port, ATMEL_US_RXRDY); | ||
385 | } | ||
295 | } | 386 | } |
296 | 387 | ||
297 | /* | 388 | /* |
@@ -302,9 +393,11 @@ static void atmel_stop_rx(struct uart_port *port) | |||
302 | if (atmel_use_dma_rx(port)) { | 393 | if (atmel_use_dma_rx(port)) { |
303 | /* disable PDC receive */ | 394 | /* disable PDC receive */ |
304 | UART_PUT_PTCR(port, ATMEL_PDC_RXTDIS); | 395 | UART_PUT_PTCR(port, ATMEL_PDC_RXTDIS); |
305 | UART_PUT_IDR(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT); | 396 | UART_PUT_IDR(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT | |
306 | } else | 397 | port->read_status_mask); |
398 | } else { | ||
307 | UART_PUT_IDR(port, ATMEL_US_RXRDY); | 399 | UART_PUT_IDR(port, ATMEL_US_RXRDY); |
400 | } | ||
308 | } | 401 | } |
309 | 402 | ||
310 | /* | 403 | /* |
@@ -427,9 +520,10 @@ static void atmel_rx_chars(struct uart_port *port) | |||
427 | */ | 520 | */ |
428 | static void atmel_tx_chars(struct uart_port *port) | 521 | static void atmel_tx_chars(struct uart_port *port) |
429 | { | 522 | { |
430 | struct circ_buf *xmit = &port->info->xmit; | 523 | struct circ_buf *xmit = &port->state->xmit; |
524 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | ||
431 | 525 | ||
432 | if (port->x_char && UART_GET_CSR(port) & ATMEL_US_TXRDY) { | 526 | if (port->x_char && UART_GET_CSR(port) & atmel_port->tx_done_mask) { |
433 | UART_PUT_CHAR(port, port->x_char); | 527 | UART_PUT_CHAR(port, port->x_char); |
434 | port->icount.tx++; | 528 | port->icount.tx++; |
435 | port->x_char = 0; | 529 | port->x_char = 0; |
@@ -437,7 +531,7 @@ static void atmel_tx_chars(struct uart_port *port) | |||
437 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) | 531 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) |
438 | return; | 532 | return; |
439 | 533 | ||
440 | while (UART_GET_CSR(port) & ATMEL_US_TXRDY) { | 534 | while (UART_GET_CSR(port) & atmel_port->tx_done_mask) { |
441 | UART_PUT_CHAR(port, xmit->buf[xmit->tail]); | 535 | UART_PUT_CHAR(port, xmit->buf[xmit->tail]); |
442 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | 536 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); |
443 | port->icount.tx++; | 537 | port->icount.tx++; |
@@ -449,7 +543,8 @@ static void atmel_tx_chars(struct uart_port *port) | |||
449 | uart_write_wakeup(port); | 543 | uart_write_wakeup(port); |
450 | 544 | ||
451 | if (!uart_circ_empty(xmit)) | 545 | if (!uart_circ_empty(xmit)) |
452 | UART_PUT_IER(port, ATMEL_US_TXRDY); | 546 | /* Enable interrupts */ |
547 | UART_PUT_IER(port, atmel_port->tx_done_mask); | ||
453 | } | 548 | } |
454 | 549 | ||
455 | /* | 550 | /* |
@@ -501,18 +596,10 @@ atmel_handle_transmit(struct uart_port *port, unsigned int pending) | |||
501 | { | 596 | { |
502 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | 597 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
503 | 598 | ||
504 | if (atmel_use_dma_tx(port)) { | 599 | if (pending & atmel_port->tx_done_mask) { |
505 | /* PDC transmit */ | 600 | /* Either PDC or interrupt transmission */ |
506 | if (pending & (ATMEL_US_ENDTX | ATMEL_US_TXBUFE)) { | 601 | UART_PUT_IDR(port, atmel_port->tx_done_mask); |
507 | UART_PUT_IDR(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE); | 602 | tasklet_schedule(&atmel_port->tasklet); |
508 | tasklet_schedule(&atmel_port->tasklet); | ||
509 | } | ||
510 | } else { | ||
511 | /* Interrupt transmit */ | ||
512 | if (pending & ATMEL_US_TXRDY) { | ||
513 | UART_PUT_IDR(port, ATMEL_US_TXRDY); | ||
514 | tasklet_schedule(&atmel_port->tasklet); | ||
515 | } | ||
516 | } | 603 | } |
517 | } | 604 | } |
518 | 605 | ||
@@ -560,7 +647,7 @@ static irqreturn_t atmel_interrupt(int irq, void *dev_id) | |||
560 | static void atmel_tx_dma(struct uart_port *port) | 647 | static void atmel_tx_dma(struct uart_port *port) |
561 | { | 648 | { |
562 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | 649 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
563 | struct circ_buf *xmit = &port->info->xmit; | 650 | struct circ_buf *xmit = &port->state->xmit; |
564 | struct atmel_dma_buffer *pdc = &atmel_port->pdc_tx; | 651 | struct atmel_dma_buffer *pdc = &atmel_port->pdc_tx; |
565 | int count; | 652 | int count; |
566 | 653 | ||
@@ -590,9 +677,15 @@ static void atmel_tx_dma(struct uart_port *port) | |||
590 | 677 | ||
591 | UART_PUT_TPR(port, pdc->dma_addr + xmit->tail); | 678 | UART_PUT_TPR(port, pdc->dma_addr + xmit->tail); |
592 | UART_PUT_TCR(port, count); | 679 | UART_PUT_TCR(port, count); |
593 | /* re-enable PDC transmit and interrupts */ | 680 | /* re-enable PDC transmit */ |
594 | UART_PUT_PTCR(port, ATMEL_PDC_TXTEN); | 681 | UART_PUT_PTCR(port, ATMEL_PDC_TXTEN); |
595 | UART_PUT_IER(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE); | 682 | /* Enable interrupts */ |
683 | UART_PUT_IER(port, atmel_port->tx_done_mask); | ||
684 | } else { | ||
685 | if (atmel_port->rs485.flags & SER_RS485_ENABLED) { | ||
686 | /* DMA done, stop TX, start RX for RS485 */ | ||
687 | atmel_start_rx(port); | ||
688 | } | ||
596 | } | 689 | } |
597 | 690 | ||
598 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 691 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
@@ -663,14 +756,14 @@ static void atmel_rx_from_ring(struct uart_port *port) | |||
663 | * uart_start(), which takes the lock. | 756 | * uart_start(), which takes the lock. |
664 | */ | 757 | */ |
665 | spin_unlock(&port->lock); | 758 | spin_unlock(&port->lock); |
666 | tty_flip_buffer_push(port->info->port.tty); | 759 | tty_flip_buffer_push(port->state->port.tty); |
667 | spin_lock(&port->lock); | 760 | spin_lock(&port->lock); |
668 | } | 761 | } |
669 | 762 | ||
670 | static void atmel_rx_from_dma(struct uart_port *port) | 763 | static void atmel_rx_from_dma(struct uart_port *port) |
671 | { | 764 | { |
672 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | 765 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
673 | struct tty_struct *tty = port->info->port.tty; | 766 | struct tty_struct *tty = port->state->port.tty; |
674 | struct atmel_dma_buffer *pdc; | 767 | struct atmel_dma_buffer *pdc; |
675 | int rx_idx = atmel_port->pdc_rx_idx; | 768 | int rx_idx = atmel_port->pdc_rx_idx; |
676 | unsigned int head; | 769 | unsigned int head; |
@@ -776,7 +869,7 @@ static void atmel_tasklet_func(unsigned long data) | |||
776 | if (status_change & ATMEL_US_CTS) | 869 | if (status_change & ATMEL_US_CTS) |
777 | uart_handle_cts_change(port, !(status & ATMEL_US_CTS)); | 870 | uart_handle_cts_change(port, !(status & ATMEL_US_CTS)); |
778 | 871 | ||
779 | wake_up_interruptible(&port->info->delta_msr_wait); | 872 | wake_up_interruptible(&port->state->port.delta_msr_wait); |
780 | 873 | ||
781 | atmel_port->irq_status_prev = status; | 874 | atmel_port->irq_status_prev = status; |
782 | } | 875 | } |
@@ -795,7 +888,7 @@ static void atmel_tasklet_func(unsigned long data) | |||
795 | static int atmel_startup(struct uart_port *port) | 888 | static int atmel_startup(struct uart_port *port) |
796 | { | 889 | { |
797 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | 890 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
798 | struct tty_struct *tty = port->info->port.tty; | 891 | struct tty_struct *tty = port->state->port.tty; |
799 | int retval; | 892 | int retval; |
800 | 893 | ||
801 | /* | 894 | /* |
@@ -854,7 +947,7 @@ static int atmel_startup(struct uart_port *port) | |||
854 | } | 947 | } |
855 | if (atmel_use_dma_tx(port)) { | 948 | if (atmel_use_dma_tx(port)) { |
856 | struct atmel_dma_buffer *pdc = &atmel_port->pdc_tx; | 949 | struct atmel_dma_buffer *pdc = &atmel_port->pdc_tx; |
857 | struct circ_buf *xmit = &port->info->xmit; | 950 | struct circ_buf *xmit = &port->state->xmit; |
858 | 951 | ||
859 | pdc->buf = xmit->buf; | 952 | pdc->buf = xmit->buf; |
860 | pdc->dma_addr = dma_map_single(port->dev, | 953 | pdc->dma_addr = dma_map_single(port->dev, |
@@ -1017,6 +1110,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1017 | { | 1110 | { |
1018 | unsigned long flags; | 1111 | unsigned long flags; |
1019 | unsigned int mode, imr, quot, baud; | 1112 | unsigned int mode, imr, quot, baud; |
1113 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | ||
1020 | 1114 | ||
1021 | /* Get current mode register */ | 1115 | /* Get current mode register */ |
1022 | mode = UART_GET_MR(port) & ~(ATMEL_US_USCLKS | ATMEL_US_CHRL | 1116 | mode = UART_GET_MR(port) & ~(ATMEL_US_USCLKS | ATMEL_US_CHRL |
@@ -1115,6 +1209,19 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1115 | /* disable receiver and transmitter */ | 1209 | /* disable receiver and transmitter */ |
1116 | UART_PUT_CR(port, ATMEL_US_TXDIS | ATMEL_US_RXDIS); | 1210 | UART_PUT_CR(port, ATMEL_US_TXDIS | ATMEL_US_RXDIS); |
1117 | 1211 | ||
1212 | /* Resetting serial mode to RS232 (0x0) */ | ||
1213 | mode &= ~ATMEL_US_USMODE; | ||
1214 | |||
1215 | if (atmel_port->rs485.flags & SER_RS485_ENABLED) { | ||
1216 | dev_dbg(port->dev, "Setting UART to RS485\n"); | ||
1217 | if (atmel_port->rs485.flags & SER_RS485_RTS_AFTER_SEND) | ||
1218 | UART_PUT_TTGR(port, | ||
1219 | atmel_port->rs485.delay_rts_after_send); | ||
1220 | mode |= ATMEL_US_USMODE_RS485; | ||
1221 | } else { | ||
1222 | dev_dbg(port->dev, "Setting UART to RS232\n"); | ||
1223 | } | ||
1224 | |||
1118 | /* set the parity, stop bits and data size */ | 1225 | /* set the parity, stop bits and data size */ |
1119 | UART_PUT_MR(port, mode); | 1226 | UART_PUT_MR(port, mode); |
1120 | 1227 | ||
@@ -1213,6 +1320,53 @@ static int atmel_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
1213 | return ret; | 1320 | return ret; |
1214 | } | 1321 | } |
1215 | 1322 | ||
1323 | #ifdef CONFIG_CONSOLE_POLL | ||
1324 | static int atmel_poll_get_char(struct uart_port *port) | ||
1325 | { | ||
1326 | while (!(UART_GET_CSR(port) & ATMEL_US_RXRDY)) | ||
1327 | cpu_relax(); | ||
1328 | |||
1329 | return UART_GET_CHAR(port); | ||
1330 | } | ||
1331 | |||
1332 | static void atmel_poll_put_char(struct uart_port *port, unsigned char ch) | ||
1333 | { | ||
1334 | while (!(UART_GET_CSR(port) & ATMEL_US_TXRDY)) | ||
1335 | cpu_relax(); | ||
1336 | |||
1337 | UART_PUT_CHAR(port, ch); | ||
1338 | } | ||
1339 | #endif | ||
1340 | |||
1341 | static int | ||
1342 | atmel_ioctl(struct uart_port *port, unsigned int cmd, unsigned long arg) | ||
1343 | { | ||
1344 | struct serial_rs485 rs485conf; | ||
1345 | |||
1346 | switch (cmd) { | ||
1347 | case TIOCSRS485: | ||
1348 | if (copy_from_user(&rs485conf, (struct serial_rs485 *) arg, | ||
1349 | sizeof(rs485conf))) | ||
1350 | return -EFAULT; | ||
1351 | |||
1352 | atmel_config_rs485(port, &rs485conf); | ||
1353 | break; | ||
1354 | |||
1355 | case TIOCGRS485: | ||
1356 | if (copy_to_user((struct serial_rs485 *) arg, | ||
1357 | &(to_atmel_uart_port(port)->rs485), | ||
1358 | sizeof(rs485conf))) | ||
1359 | return -EFAULT; | ||
1360 | break; | ||
1361 | |||
1362 | default: | ||
1363 | return -ENOIOCTLCMD; | ||
1364 | } | ||
1365 | return 0; | ||
1366 | } | ||
1367 | |||
1368 | |||
1369 | |||
1216 | static struct uart_ops atmel_pops = { | 1370 | static struct uart_ops atmel_pops = { |
1217 | .tx_empty = atmel_tx_empty, | 1371 | .tx_empty = atmel_tx_empty, |
1218 | .set_mctrl = atmel_set_mctrl, | 1372 | .set_mctrl = atmel_set_mctrl, |
@@ -1232,6 +1386,11 @@ static struct uart_ops atmel_pops = { | |||
1232 | .config_port = atmel_config_port, | 1386 | .config_port = atmel_config_port, |
1233 | .verify_port = atmel_verify_port, | 1387 | .verify_port = atmel_verify_port, |
1234 | .pm = atmel_serial_pm, | 1388 | .pm = atmel_serial_pm, |
1389 | .ioctl = atmel_ioctl, | ||
1390 | #ifdef CONFIG_CONSOLE_POLL | ||
1391 | .poll_get_char = atmel_poll_get_char, | ||
1392 | .poll_put_char = atmel_poll_put_char, | ||
1393 | #endif | ||
1235 | }; | 1394 | }; |
1236 | 1395 | ||
1237 | /* | 1396 | /* |
@@ -1243,13 +1402,12 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port, | |||
1243 | struct uart_port *port = &atmel_port->uart; | 1402 | struct uart_port *port = &atmel_port->uart; |
1244 | struct atmel_uart_data *data = pdev->dev.platform_data; | 1403 | struct atmel_uart_data *data = pdev->dev.platform_data; |
1245 | 1404 | ||
1246 | port->iotype = UPIO_MEM; | 1405 | port->iotype = UPIO_MEM; |
1247 | port->flags = UPF_BOOT_AUTOCONF; | 1406 | port->flags = UPF_BOOT_AUTOCONF; |
1248 | port->ops = &atmel_pops; | 1407 | port->ops = &atmel_pops; |
1249 | port->fifosize = 1; | 1408 | port->fifosize = 1; |
1250 | port->line = pdev->id; | 1409 | port->line = pdev->id; |
1251 | port->dev = &pdev->dev; | 1410 | port->dev = &pdev->dev; |
1252 | |||
1253 | port->mapbase = pdev->resource[0].start; | 1411 | port->mapbase = pdev->resource[0].start; |
1254 | port->irq = pdev->resource[1].start; | 1412 | port->irq = pdev->resource[1].start; |
1255 | 1413 | ||
@@ -1277,8 +1435,16 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port, | |||
1277 | 1435 | ||
1278 | atmel_port->use_dma_rx = data->use_dma_rx; | 1436 | atmel_port->use_dma_rx = data->use_dma_rx; |
1279 | atmel_port->use_dma_tx = data->use_dma_tx; | 1437 | atmel_port->use_dma_tx = data->use_dma_tx; |
1280 | if (atmel_use_dma_tx(port)) | 1438 | atmel_port->rs485 = data->rs485; |
1439 | /* Use TXEMPTY for interrupt when rs485 else TXRDY or ENDTX|TXBUFE */ | ||
1440 | if (atmel_port->rs485.flags & SER_RS485_ENABLED) | ||
1441 | atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; | ||
1442 | else if (atmel_use_dma_tx(port)) { | ||
1281 | port->fifosize = PDC_BUFFER_SIZE; | 1443 | port->fifosize = PDC_BUFFER_SIZE; |
1444 | atmel_port->tx_done_mask = ATMEL_US_ENDTX | ATMEL_US_TXBUFE; | ||
1445 | } else { | ||
1446 | atmel_port->tx_done_mask = ATMEL_US_TXRDY; | ||
1447 | } | ||
1282 | } | 1448 | } |
1283 | 1449 | ||
1284 | /* | 1450 | /* |
@@ -1312,6 +1478,7 @@ static void atmel_console_putchar(struct uart_port *port, int ch) | |||
1312 | static void atmel_console_write(struct console *co, const char *s, u_int count) | 1478 | static void atmel_console_write(struct console *co, const char *s, u_int count) |
1313 | { | 1479 | { |
1314 | struct uart_port *port = &atmel_ports[co->index].uart; | 1480 | struct uart_port *port = &atmel_ports[co->index].uart; |
1481 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | ||
1315 | unsigned int status, imr; | 1482 | unsigned int status, imr; |
1316 | unsigned int pdc_tx; | 1483 | unsigned int pdc_tx; |
1317 | 1484 | ||
@@ -1319,7 +1486,7 @@ static void atmel_console_write(struct console *co, const char *s, u_int count) | |||
1319 | * First, save IMR and then disable interrupts | 1486 | * First, save IMR and then disable interrupts |
1320 | */ | 1487 | */ |
1321 | imr = UART_GET_IMR(port); | 1488 | imr = UART_GET_IMR(port); |
1322 | UART_PUT_IDR(port, ATMEL_US_RXRDY | ATMEL_US_TXRDY); | 1489 | UART_PUT_IDR(port, ATMEL_US_RXRDY | atmel_port->tx_done_mask); |
1323 | 1490 | ||
1324 | /* Store PDC transmit status and disable it */ | 1491 | /* Store PDC transmit status and disable it */ |
1325 | pdc_tx = UART_GET_PTSR(port) & ATMEL_PDC_TXTEN; | 1492 | pdc_tx = UART_GET_PTSR(port) & ATMEL_PDC_TXTEN; |
@@ -1531,7 +1698,7 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev) | |||
1531 | void *data; | 1698 | void *data; |
1532 | int ret; | 1699 | int ret; |
1533 | 1700 | ||
1534 | BUILD_BUG_ON(!is_power_of_2(ATMEL_SERIAL_RINGSIZE)); | 1701 | BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1)); |
1535 | 1702 | ||
1536 | port = &atmel_ports[pdev->id]; | 1703 | port = &atmel_ports[pdev->id]; |
1537 | port->backup_imr = 0; | 1704 | port->backup_imr = 0; |
@@ -1551,6 +1718,7 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev) | |||
1551 | if (ret) | 1718 | if (ret) |
1552 | goto err_add_port; | 1719 | goto err_add_port; |
1553 | 1720 | ||
1721 | #ifdef CONFIG_SERIAL_ATMEL_CONSOLE | ||
1554 | if (atmel_is_console_port(&port->uart) | 1722 | if (atmel_is_console_port(&port->uart) |
1555 | && ATMEL_CONSOLE_DEVICE->flags & CON_ENABLED) { | 1723 | && ATMEL_CONSOLE_DEVICE->flags & CON_ENABLED) { |
1556 | /* | 1724 | /* |
@@ -1559,6 +1727,7 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev) | |||
1559 | */ | 1727 | */ |
1560 | clk_disable(port->clk); | 1728 | clk_disable(port->clk); |
1561 | } | 1729 | } |
1730 | #endif | ||
1562 | 1731 | ||
1563 | device_init_wakeup(&pdev->dev, 1); | 1732 | device_init_wakeup(&pdev->dev, 1); |
1564 | platform_set_drvdata(pdev, port); | 1733 | platform_set_drvdata(pdev, port); |
diff --git a/drivers/serial/bcm63xx_uart.c b/drivers/serial/bcm63xx_uart.c new file mode 100644 index 000000000000..a1a0e55d0807 --- /dev/null +++ b/drivers/serial/bcm63xx_uart.c | |||
@@ -0,0 +1,891 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Derived from many drivers using generic_serial interface. | ||
7 | * | ||
8 | * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> | ||
9 | * | ||
10 | * Serial driver for BCM63xx integrated UART. | ||
11 | * | ||
12 | * Hardware flow control was _not_ tested since I only have RX/TX on | ||
13 | * my board. | ||
14 | */ | ||
15 | |||
16 | #if defined(CONFIG_SERIAL_BCM63XX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | ||
17 | #define SUPPORT_SYSRQ | ||
18 | #endif | ||
19 | |||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/console.h> | ||
26 | #include <linux/clk.h> | ||
27 | #include <linux/tty.h> | ||
28 | #include <linux/tty_flip.h> | ||
29 | #include <linux/sysrq.h> | ||
30 | #include <linux/serial.h> | ||
31 | #include <linux/serial_core.h> | ||
32 | |||
33 | #include <bcm63xx_clk.h> | ||
34 | #include <bcm63xx_irq.h> | ||
35 | #include <bcm63xx_regs.h> | ||
36 | #include <bcm63xx_io.h> | ||
37 | |||
38 | #define BCM63XX_NR_UARTS 2 | ||
39 | |||
40 | static struct uart_port ports[BCM63XX_NR_UARTS]; | ||
41 | |||
42 | /* | ||
43 | * rx interrupt mask / stat | ||
44 | * | ||
45 | * mask: | ||
46 | * - rx fifo full | ||
47 | * - rx fifo above threshold | ||
48 | * - rx fifo not empty for too long | ||
49 | */ | ||
50 | #define UART_RX_INT_MASK (UART_IR_MASK(UART_IR_RXOVER) | \ | ||
51 | UART_IR_MASK(UART_IR_RXTHRESH) | \ | ||
52 | UART_IR_MASK(UART_IR_RXTIMEOUT)) | ||
53 | |||
54 | #define UART_RX_INT_STAT (UART_IR_STAT(UART_IR_RXOVER) | \ | ||
55 | UART_IR_STAT(UART_IR_RXTHRESH) | \ | ||
56 | UART_IR_STAT(UART_IR_RXTIMEOUT)) | ||
57 | |||
58 | /* | ||
59 | * tx interrupt mask / stat | ||
60 | * | ||
61 | * mask: | ||
62 | * - tx fifo empty | ||
63 | * - tx fifo below threshold | ||
64 | */ | ||
65 | #define UART_TX_INT_MASK (UART_IR_MASK(UART_IR_TXEMPTY) | \ | ||
66 | UART_IR_MASK(UART_IR_TXTRESH)) | ||
67 | |||
68 | #define UART_TX_INT_STAT (UART_IR_STAT(UART_IR_TXEMPTY) | \ | ||
69 | UART_IR_STAT(UART_IR_TXTRESH)) | ||
70 | |||
71 | /* | ||
72 | * external input interrupt | ||
73 | * | ||
74 | * mask: any edge on CTS, DCD | ||
75 | */ | ||
76 | #define UART_EXTINP_INT_MASK (UART_EXTINP_IRMASK(UART_EXTINP_IR_CTS) | \ | ||
77 | UART_EXTINP_IRMASK(UART_EXTINP_IR_DCD)) | ||
78 | |||
79 | /* | ||
80 | * handy uart register accessor | ||
81 | */ | ||
82 | static inline unsigned int bcm_uart_readl(struct uart_port *port, | ||
83 | unsigned int offset) | ||
84 | { | ||
85 | return bcm_readl(port->membase + offset); | ||
86 | } | ||
87 | |||
88 | static inline void bcm_uart_writel(struct uart_port *port, | ||
89 | unsigned int value, unsigned int offset) | ||
90 | { | ||
91 | bcm_writel(value, port->membase + offset); | ||
92 | } | ||
93 | |||
94 | /* | ||
95 | * serial core request to check if uart tx fifo is empty | ||
96 | */ | ||
97 | static unsigned int bcm_uart_tx_empty(struct uart_port *port) | ||
98 | { | ||
99 | unsigned int val; | ||
100 | |||
101 | val = bcm_uart_readl(port, UART_IR_REG); | ||
102 | return (val & UART_IR_STAT(UART_IR_TXEMPTY)) ? 1 : 0; | ||
103 | } | ||
104 | |||
105 | /* | ||
106 | * serial core request to set RTS and DTR pin state and loopback mode | ||
107 | */ | ||
108 | static void bcm_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
109 | { | ||
110 | unsigned int val; | ||
111 | |||
112 | val = bcm_uart_readl(port, UART_MCTL_REG); | ||
113 | val &= ~(UART_MCTL_DTR_MASK | UART_MCTL_RTS_MASK); | ||
114 | /* invert of written value is reflected on the pin */ | ||
115 | if (!(mctrl & TIOCM_DTR)) | ||
116 | val |= UART_MCTL_DTR_MASK; | ||
117 | if (!(mctrl & TIOCM_RTS)) | ||
118 | val |= UART_MCTL_RTS_MASK; | ||
119 | bcm_uart_writel(port, val, UART_MCTL_REG); | ||
120 | |||
121 | val = bcm_uart_readl(port, UART_CTL_REG); | ||
122 | if (mctrl & TIOCM_LOOP) | ||
123 | val |= UART_CTL_LOOPBACK_MASK; | ||
124 | else | ||
125 | val &= ~UART_CTL_LOOPBACK_MASK; | ||
126 | bcm_uart_writel(port, val, UART_CTL_REG); | ||
127 | } | ||
128 | |||
129 | /* | ||
130 | * serial core request to return RI, CTS, DCD and DSR pin state | ||
131 | */ | ||
132 | static unsigned int bcm_uart_get_mctrl(struct uart_port *port) | ||
133 | { | ||
134 | unsigned int val, mctrl; | ||
135 | |||
136 | mctrl = 0; | ||
137 | val = bcm_uart_readl(port, UART_EXTINP_REG); | ||
138 | if (val & UART_EXTINP_RI_MASK) | ||
139 | mctrl |= TIOCM_RI; | ||
140 | if (val & UART_EXTINP_CTS_MASK) | ||
141 | mctrl |= TIOCM_CTS; | ||
142 | if (val & UART_EXTINP_DCD_MASK) | ||
143 | mctrl |= TIOCM_CD; | ||
144 | if (val & UART_EXTINP_DSR_MASK) | ||
145 | mctrl |= TIOCM_DSR; | ||
146 | return mctrl; | ||
147 | } | ||
148 | |||
149 | /* | ||
150 | * serial core request to disable tx ASAP (used for flow control) | ||
151 | */ | ||
152 | static void bcm_uart_stop_tx(struct uart_port *port) | ||
153 | { | ||
154 | unsigned int val; | ||
155 | |||
156 | val = bcm_uart_readl(port, UART_CTL_REG); | ||
157 | val &= ~(UART_CTL_TXEN_MASK); | ||
158 | bcm_uart_writel(port, val, UART_CTL_REG); | ||
159 | |||
160 | val = bcm_uart_readl(port, UART_IR_REG); | ||
161 | val &= ~UART_TX_INT_MASK; | ||
162 | bcm_uart_writel(port, val, UART_IR_REG); | ||
163 | } | ||
164 | |||
165 | /* | ||
166 | * serial core request to (re)enable tx | ||
167 | */ | ||
168 | static void bcm_uart_start_tx(struct uart_port *port) | ||
169 | { | ||
170 | unsigned int val; | ||
171 | |||
172 | val = bcm_uart_readl(port, UART_IR_REG); | ||
173 | val |= UART_TX_INT_MASK; | ||
174 | bcm_uart_writel(port, val, UART_IR_REG); | ||
175 | |||
176 | val = bcm_uart_readl(port, UART_CTL_REG); | ||
177 | val |= UART_CTL_TXEN_MASK; | ||
178 | bcm_uart_writel(port, val, UART_CTL_REG); | ||
179 | } | ||
180 | |||
181 | /* | ||
182 | * serial core request to stop rx, called before port shutdown | ||
183 | */ | ||
184 | static void bcm_uart_stop_rx(struct uart_port *port) | ||
185 | { | ||
186 | unsigned int val; | ||
187 | |||
188 | val = bcm_uart_readl(port, UART_IR_REG); | ||
189 | val &= ~UART_RX_INT_MASK; | ||
190 | bcm_uart_writel(port, val, UART_IR_REG); | ||
191 | } | ||
192 | |||
193 | /* | ||
194 | * serial core request to enable modem status interrupt reporting | ||
195 | */ | ||
196 | static void bcm_uart_enable_ms(struct uart_port *port) | ||
197 | { | ||
198 | unsigned int val; | ||
199 | |||
200 | val = bcm_uart_readl(port, UART_IR_REG); | ||
201 | val |= UART_IR_MASK(UART_IR_EXTIP); | ||
202 | bcm_uart_writel(port, val, UART_IR_REG); | ||
203 | } | ||
204 | |||
205 | /* | ||
206 | * serial core request to start/stop emitting break char | ||
207 | */ | ||
208 | static void bcm_uart_break_ctl(struct uart_port *port, int ctl) | ||
209 | { | ||
210 | unsigned long flags; | ||
211 | unsigned int val; | ||
212 | |||
213 | spin_lock_irqsave(&port->lock, flags); | ||
214 | |||
215 | val = bcm_uart_readl(port, UART_CTL_REG); | ||
216 | if (ctl) | ||
217 | val |= UART_CTL_XMITBRK_MASK; | ||
218 | else | ||
219 | val &= ~UART_CTL_XMITBRK_MASK; | ||
220 | bcm_uart_writel(port, val, UART_CTL_REG); | ||
221 | |||
222 | spin_unlock_irqrestore(&port->lock, flags); | ||
223 | } | ||
224 | |||
225 | /* | ||
226 | * return port type in string format | ||
227 | */ | ||
228 | static const char *bcm_uart_type(struct uart_port *port) | ||
229 | { | ||
230 | return (port->type == PORT_BCM63XX) ? "bcm63xx_uart" : NULL; | ||
231 | } | ||
232 | |||
233 | /* | ||
234 | * read all chars in rx fifo and send them to core | ||
235 | */ | ||
236 | static void bcm_uart_do_rx(struct uart_port *port) | ||
237 | { | ||
238 | struct tty_struct *tty; | ||
239 | unsigned int max_count; | ||
240 | |||
241 | /* limit number of char read in interrupt, should not be | ||
242 | * higher than fifo size anyway since we're much faster than | ||
243 | * serial port */ | ||
244 | max_count = 32; | ||
245 | tty = port->state->port.tty; | ||
246 | do { | ||
247 | unsigned int iestat, c, cstat; | ||
248 | char flag; | ||
249 | |||
250 | /* get overrun/fifo empty information from ier | ||
251 | * register */ | ||
252 | iestat = bcm_uart_readl(port, UART_IR_REG); | ||
253 | if (!(iestat & UART_IR_STAT(UART_IR_RXNOTEMPTY))) | ||
254 | break; | ||
255 | |||
256 | cstat = c = bcm_uart_readl(port, UART_FIFO_REG); | ||
257 | port->icount.rx++; | ||
258 | flag = TTY_NORMAL; | ||
259 | c &= 0xff; | ||
260 | |||
261 | if (unlikely((cstat & UART_FIFO_ANYERR_MASK))) { | ||
262 | /* do stats first */ | ||
263 | if (cstat & UART_FIFO_BRKDET_MASK) { | ||
264 | port->icount.brk++; | ||
265 | if (uart_handle_break(port)) | ||
266 | continue; | ||
267 | } | ||
268 | |||
269 | if (cstat & UART_FIFO_PARERR_MASK) | ||
270 | port->icount.parity++; | ||
271 | if (cstat & UART_FIFO_FRAMEERR_MASK) | ||
272 | port->icount.frame++; | ||
273 | |||
274 | /* update flag wrt read_status_mask */ | ||
275 | cstat &= port->read_status_mask; | ||
276 | if (cstat & UART_FIFO_BRKDET_MASK) | ||
277 | flag = TTY_BREAK; | ||
278 | if (cstat & UART_FIFO_FRAMEERR_MASK) | ||
279 | flag = TTY_FRAME; | ||
280 | if (cstat & UART_FIFO_PARERR_MASK) | ||
281 | flag = TTY_PARITY; | ||
282 | } | ||
283 | |||
284 | if (uart_handle_sysrq_char(port, c)) | ||
285 | continue; | ||
286 | |||
287 | if (unlikely(iestat & UART_IR_STAT(UART_IR_RXOVER))) { | ||
288 | port->icount.overrun++; | ||
289 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
290 | } | ||
291 | |||
292 | if ((cstat & port->ignore_status_mask) == 0) | ||
293 | tty_insert_flip_char(tty, c, flag); | ||
294 | |||
295 | } while (--max_count); | ||
296 | |||
297 | tty_flip_buffer_push(tty); | ||
298 | } | ||
299 | |||
300 | /* | ||
301 | * fill tx fifo with chars to send, stop when fifo is about to be full | ||
302 | * or when all chars have been sent. | ||
303 | */ | ||
304 | static void bcm_uart_do_tx(struct uart_port *port) | ||
305 | { | ||
306 | struct circ_buf *xmit; | ||
307 | unsigned int val, max_count; | ||
308 | |||
309 | if (port->x_char) { | ||
310 | bcm_uart_writel(port, port->x_char, UART_FIFO_REG); | ||
311 | port->icount.tx++; | ||
312 | port->x_char = 0; | ||
313 | return; | ||
314 | } | ||
315 | |||
316 | if (uart_tx_stopped(port)) { | ||
317 | bcm_uart_stop_tx(port); | ||
318 | return; | ||
319 | } | ||
320 | |||
321 | xmit = &port->state->xmit; | ||
322 | if (uart_circ_empty(xmit)) | ||
323 | goto txq_empty; | ||
324 | |||
325 | val = bcm_uart_readl(port, UART_MCTL_REG); | ||
326 | val = (val & UART_MCTL_TXFIFOFILL_MASK) >> UART_MCTL_TXFIFOFILL_SHIFT; | ||
327 | max_count = port->fifosize - val; | ||
328 | |||
329 | while (max_count--) { | ||
330 | unsigned int c; | ||
331 | |||
332 | c = xmit->buf[xmit->tail]; | ||
333 | bcm_uart_writel(port, c, UART_FIFO_REG); | ||
334 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
335 | port->icount.tx++; | ||
336 | if (uart_circ_empty(xmit)) | ||
337 | break; | ||
338 | } | ||
339 | |||
340 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
341 | uart_write_wakeup(port); | ||
342 | |||
343 | if (uart_circ_empty(xmit)) | ||
344 | goto txq_empty; | ||
345 | return; | ||
346 | |||
347 | txq_empty: | ||
348 | /* nothing to send, disable transmit interrupt */ | ||
349 | val = bcm_uart_readl(port, UART_IR_REG); | ||
350 | val &= ~UART_TX_INT_MASK; | ||
351 | bcm_uart_writel(port, val, UART_IR_REG); | ||
352 | return; | ||
353 | } | ||
354 | |||
355 | /* | ||
356 | * process uart interrupt | ||
357 | */ | ||
358 | static irqreturn_t bcm_uart_interrupt(int irq, void *dev_id) | ||
359 | { | ||
360 | struct uart_port *port; | ||
361 | unsigned int irqstat; | ||
362 | |||
363 | port = dev_id; | ||
364 | spin_lock(&port->lock); | ||
365 | |||
366 | irqstat = bcm_uart_readl(port, UART_IR_REG); | ||
367 | if (irqstat & UART_RX_INT_STAT) | ||
368 | bcm_uart_do_rx(port); | ||
369 | |||
370 | if (irqstat & UART_TX_INT_STAT) | ||
371 | bcm_uart_do_tx(port); | ||
372 | |||
373 | if (irqstat & UART_IR_MASK(UART_IR_EXTIP)) { | ||
374 | unsigned int estat; | ||
375 | |||
376 | estat = bcm_uart_readl(port, UART_EXTINP_REG); | ||
377 | if (estat & UART_EXTINP_IRSTAT(UART_EXTINP_IR_CTS)) | ||
378 | uart_handle_cts_change(port, | ||
379 | estat & UART_EXTINP_CTS_MASK); | ||
380 | if (estat & UART_EXTINP_IRSTAT(UART_EXTINP_IR_DCD)) | ||
381 | uart_handle_dcd_change(port, | ||
382 | estat & UART_EXTINP_DCD_MASK); | ||
383 | } | ||
384 | |||
385 | spin_unlock(&port->lock); | ||
386 | return IRQ_HANDLED; | ||
387 | } | ||
388 | |||
389 | /* | ||
390 | * enable rx & tx operation on uart | ||
391 | */ | ||
392 | static void bcm_uart_enable(struct uart_port *port) | ||
393 | { | ||
394 | unsigned int val; | ||
395 | |||
396 | val = bcm_uart_readl(port, UART_CTL_REG); | ||
397 | val |= (UART_CTL_BRGEN_MASK | UART_CTL_TXEN_MASK | UART_CTL_RXEN_MASK); | ||
398 | bcm_uart_writel(port, val, UART_CTL_REG); | ||
399 | } | ||
400 | |||
401 | /* | ||
402 | * disable rx & tx operation on uart | ||
403 | */ | ||
404 | static void bcm_uart_disable(struct uart_port *port) | ||
405 | { | ||
406 | unsigned int val; | ||
407 | |||
408 | val = bcm_uart_readl(port, UART_CTL_REG); | ||
409 | val &= ~(UART_CTL_BRGEN_MASK | UART_CTL_TXEN_MASK | | ||
410 | UART_CTL_RXEN_MASK); | ||
411 | bcm_uart_writel(port, val, UART_CTL_REG); | ||
412 | } | ||
413 | |||
414 | /* | ||
415 | * clear all unread data in rx fifo and unsent data in tx fifo | ||
416 | */ | ||
417 | static void bcm_uart_flush(struct uart_port *port) | ||
418 | { | ||
419 | unsigned int val; | ||
420 | |||
421 | /* empty rx and tx fifo */ | ||
422 | val = bcm_uart_readl(port, UART_CTL_REG); | ||
423 | val |= UART_CTL_RSTRXFIFO_MASK | UART_CTL_RSTTXFIFO_MASK; | ||
424 | bcm_uart_writel(port, val, UART_CTL_REG); | ||
425 | |||
426 | /* read any pending char to make sure all irq status are | ||
427 | * cleared */ | ||
428 | (void)bcm_uart_readl(port, UART_FIFO_REG); | ||
429 | } | ||
430 | |||
431 | /* | ||
432 | * serial core request to initialize uart and start rx operation | ||
433 | */ | ||
434 | static int bcm_uart_startup(struct uart_port *port) | ||
435 | { | ||
436 | unsigned int val; | ||
437 | int ret; | ||
438 | |||
439 | /* mask all irq and flush port */ | ||
440 | bcm_uart_disable(port); | ||
441 | bcm_uart_writel(port, 0, UART_IR_REG); | ||
442 | bcm_uart_flush(port); | ||
443 | |||
444 | /* clear any pending external input interrupt */ | ||
445 | (void)bcm_uart_readl(port, UART_EXTINP_REG); | ||
446 | |||
447 | /* set rx/tx fifo thresh to fifo half size */ | ||
448 | val = bcm_uart_readl(port, UART_MCTL_REG); | ||
449 | val &= ~(UART_MCTL_RXFIFOTHRESH_MASK | UART_MCTL_TXFIFOTHRESH_MASK); | ||
450 | val |= (port->fifosize / 2) << UART_MCTL_RXFIFOTHRESH_SHIFT; | ||
451 | val |= (port->fifosize / 2) << UART_MCTL_TXFIFOTHRESH_SHIFT; | ||
452 | bcm_uart_writel(port, val, UART_MCTL_REG); | ||
453 | |||
454 | /* set rx fifo timeout to 1 char time */ | ||
455 | val = bcm_uart_readl(port, UART_CTL_REG); | ||
456 | val &= ~UART_CTL_RXTMOUTCNT_MASK; | ||
457 | val |= 1 << UART_CTL_RXTMOUTCNT_SHIFT; | ||
458 | bcm_uart_writel(port, val, UART_CTL_REG); | ||
459 | |||
460 | /* report any edge on dcd and cts */ | ||
461 | val = UART_EXTINP_INT_MASK; | ||
462 | val |= UART_EXTINP_DCD_NOSENSE_MASK; | ||
463 | val |= UART_EXTINP_CTS_NOSENSE_MASK; | ||
464 | bcm_uart_writel(port, val, UART_EXTINP_REG); | ||
465 | |||
466 | /* register irq and enable rx interrupts */ | ||
467 | ret = request_irq(port->irq, bcm_uart_interrupt, 0, | ||
468 | bcm_uart_type(port), port); | ||
469 | if (ret) | ||
470 | return ret; | ||
471 | bcm_uart_writel(port, UART_RX_INT_MASK, UART_IR_REG); | ||
472 | bcm_uart_enable(port); | ||
473 | return 0; | ||
474 | } | ||
475 | |||
476 | /* | ||
477 | * serial core request to flush & disable uart | ||
478 | */ | ||
479 | static void bcm_uart_shutdown(struct uart_port *port) | ||
480 | { | ||
481 | unsigned long flags; | ||
482 | |||
483 | spin_lock_irqsave(&port->lock, flags); | ||
484 | bcm_uart_writel(port, 0, UART_IR_REG); | ||
485 | spin_unlock_irqrestore(&port->lock, flags); | ||
486 | |||
487 | bcm_uart_disable(port); | ||
488 | bcm_uart_flush(port); | ||
489 | free_irq(port->irq, port); | ||
490 | } | ||
491 | |||
492 | /* | ||
493 | * serial core request to change current uart setting | ||
494 | */ | ||
495 | static void bcm_uart_set_termios(struct uart_port *port, | ||
496 | struct ktermios *new, | ||
497 | struct ktermios *old) | ||
498 | { | ||
499 | unsigned int ctl, baud, quot, ier; | ||
500 | unsigned long flags; | ||
501 | |||
502 | spin_lock_irqsave(&port->lock, flags); | ||
503 | |||
504 | /* disable uart while changing speed */ | ||
505 | bcm_uart_disable(port); | ||
506 | bcm_uart_flush(port); | ||
507 | |||
508 | /* update Control register */ | ||
509 | ctl = bcm_uart_readl(port, UART_CTL_REG); | ||
510 | ctl &= ~UART_CTL_BITSPERSYM_MASK; | ||
511 | |||
512 | switch (new->c_cflag & CSIZE) { | ||
513 | case CS5: | ||
514 | ctl |= (0 << UART_CTL_BITSPERSYM_SHIFT); | ||
515 | break; | ||
516 | case CS6: | ||
517 | ctl |= (1 << UART_CTL_BITSPERSYM_SHIFT); | ||
518 | break; | ||
519 | case CS7: | ||
520 | ctl |= (2 << UART_CTL_BITSPERSYM_SHIFT); | ||
521 | break; | ||
522 | default: | ||
523 | ctl |= (3 << UART_CTL_BITSPERSYM_SHIFT); | ||
524 | break; | ||
525 | } | ||
526 | |||
527 | ctl &= ~UART_CTL_STOPBITS_MASK; | ||
528 | if (new->c_cflag & CSTOPB) | ||
529 | ctl |= UART_CTL_STOPBITS_2; | ||
530 | else | ||
531 | ctl |= UART_CTL_STOPBITS_1; | ||
532 | |||
533 | ctl &= ~(UART_CTL_RXPAREN_MASK | UART_CTL_TXPAREN_MASK); | ||
534 | if (new->c_cflag & PARENB) | ||
535 | ctl |= (UART_CTL_RXPAREN_MASK | UART_CTL_TXPAREN_MASK); | ||
536 | ctl &= ~(UART_CTL_RXPAREVEN_MASK | UART_CTL_TXPAREVEN_MASK); | ||
537 | if (new->c_cflag & PARODD) | ||
538 | ctl |= (UART_CTL_RXPAREVEN_MASK | UART_CTL_TXPAREVEN_MASK); | ||
539 | bcm_uart_writel(port, ctl, UART_CTL_REG); | ||
540 | |||
541 | /* update Baudword register */ | ||
542 | baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16); | ||
543 | quot = uart_get_divisor(port, baud) - 1; | ||
544 | bcm_uart_writel(port, quot, UART_BAUD_REG); | ||
545 | |||
546 | /* update Interrupt register */ | ||
547 | ier = bcm_uart_readl(port, UART_IR_REG); | ||
548 | |||
549 | ier &= ~UART_IR_MASK(UART_IR_EXTIP); | ||
550 | if (UART_ENABLE_MS(port, new->c_cflag)) | ||
551 | ier |= UART_IR_MASK(UART_IR_EXTIP); | ||
552 | |||
553 | bcm_uart_writel(port, ier, UART_IR_REG); | ||
554 | |||
555 | /* update read/ignore mask */ | ||
556 | port->read_status_mask = UART_FIFO_VALID_MASK; | ||
557 | if (new->c_iflag & INPCK) { | ||
558 | port->read_status_mask |= UART_FIFO_FRAMEERR_MASK; | ||
559 | port->read_status_mask |= UART_FIFO_PARERR_MASK; | ||
560 | } | ||
561 | if (new->c_iflag & (BRKINT)) | ||
562 | port->read_status_mask |= UART_FIFO_BRKDET_MASK; | ||
563 | |||
564 | port->ignore_status_mask = 0; | ||
565 | if (new->c_iflag & IGNPAR) | ||
566 | port->ignore_status_mask |= UART_FIFO_PARERR_MASK; | ||
567 | if (new->c_iflag & IGNBRK) | ||
568 | port->ignore_status_mask |= UART_FIFO_BRKDET_MASK; | ||
569 | if (!(new->c_cflag & CREAD)) | ||
570 | port->ignore_status_mask |= UART_FIFO_VALID_MASK; | ||
571 | |||
572 | uart_update_timeout(port, new->c_cflag, baud); | ||
573 | bcm_uart_enable(port); | ||
574 | spin_unlock_irqrestore(&port->lock, flags); | ||
575 | } | ||
576 | |||
577 | /* | ||
578 | * serial core request to claim uart iomem | ||
579 | */ | ||
580 | static int bcm_uart_request_port(struct uart_port *port) | ||
581 | { | ||
582 | unsigned int size; | ||
583 | |||
584 | size = RSET_UART_SIZE; | ||
585 | if (!request_mem_region(port->mapbase, size, "bcm63xx")) { | ||
586 | dev_err(port->dev, "Memory region busy\n"); | ||
587 | return -EBUSY; | ||
588 | } | ||
589 | |||
590 | port->membase = ioremap(port->mapbase, size); | ||
591 | if (!port->membase) { | ||
592 | dev_err(port->dev, "Unable to map registers\n"); | ||
593 | release_mem_region(port->mapbase, size); | ||
594 | return -EBUSY; | ||
595 | } | ||
596 | return 0; | ||
597 | } | ||
598 | |||
599 | /* | ||
600 | * serial core request to release uart iomem | ||
601 | */ | ||
602 | static void bcm_uart_release_port(struct uart_port *port) | ||
603 | { | ||
604 | release_mem_region(port->mapbase, RSET_UART_SIZE); | ||
605 | iounmap(port->membase); | ||
606 | } | ||
607 | |||
608 | /* | ||
609 | * serial core request to do any port required autoconfiguration | ||
610 | */ | ||
611 | static void bcm_uart_config_port(struct uart_port *port, int flags) | ||
612 | { | ||
613 | if (flags & UART_CONFIG_TYPE) { | ||
614 | if (bcm_uart_request_port(port)) | ||
615 | return; | ||
616 | port->type = PORT_BCM63XX; | ||
617 | } | ||
618 | } | ||
619 | |||
620 | /* | ||
621 | * serial core request to check that port information in serinfo are | ||
622 | * suitable | ||
623 | */ | ||
624 | static int bcm_uart_verify_port(struct uart_port *port, | ||
625 | struct serial_struct *serinfo) | ||
626 | { | ||
627 | if (port->type != PORT_BCM63XX) | ||
628 | return -EINVAL; | ||
629 | if (port->irq != serinfo->irq) | ||
630 | return -EINVAL; | ||
631 | if (port->iotype != serinfo->io_type) | ||
632 | return -EINVAL; | ||
633 | if (port->mapbase != (unsigned long)serinfo->iomem_base) | ||
634 | return -EINVAL; | ||
635 | return 0; | ||
636 | } | ||
637 | |||
638 | /* serial core callbacks */ | ||
639 | static struct uart_ops bcm_uart_ops = { | ||
640 | .tx_empty = bcm_uart_tx_empty, | ||
641 | .get_mctrl = bcm_uart_get_mctrl, | ||
642 | .set_mctrl = bcm_uart_set_mctrl, | ||
643 | .start_tx = bcm_uart_start_tx, | ||
644 | .stop_tx = bcm_uart_stop_tx, | ||
645 | .stop_rx = bcm_uart_stop_rx, | ||
646 | .enable_ms = bcm_uart_enable_ms, | ||
647 | .break_ctl = bcm_uart_break_ctl, | ||
648 | .startup = bcm_uart_startup, | ||
649 | .shutdown = bcm_uart_shutdown, | ||
650 | .set_termios = bcm_uart_set_termios, | ||
651 | .type = bcm_uart_type, | ||
652 | .release_port = bcm_uart_release_port, | ||
653 | .request_port = bcm_uart_request_port, | ||
654 | .config_port = bcm_uart_config_port, | ||
655 | .verify_port = bcm_uart_verify_port, | ||
656 | }; | ||
657 | |||
658 | |||
659 | |||
660 | #ifdef CONFIG_SERIAL_BCM63XX_CONSOLE | ||
661 | static inline void wait_for_xmitr(struct uart_port *port) | ||
662 | { | ||
663 | unsigned int tmout; | ||
664 | |||
665 | /* Wait up to 10ms for the character(s) to be sent. */ | ||
666 | tmout = 10000; | ||
667 | while (--tmout) { | ||
668 | unsigned int val; | ||
669 | |||
670 | val = bcm_uart_readl(port, UART_IR_REG); | ||
671 | if (val & UART_IR_STAT(UART_IR_TXEMPTY)) | ||
672 | break; | ||
673 | udelay(1); | ||
674 | } | ||
675 | |||
676 | /* Wait up to 1s for flow control if necessary */ | ||
677 | if (port->flags & UPF_CONS_FLOW) { | ||
678 | tmout = 1000000; | ||
679 | while (--tmout) { | ||
680 | unsigned int val; | ||
681 | |||
682 | val = bcm_uart_readl(port, UART_EXTINP_REG); | ||
683 | if (val & UART_EXTINP_CTS_MASK) | ||
684 | break; | ||
685 | udelay(1); | ||
686 | } | ||
687 | } | ||
688 | } | ||
689 | |||
690 | /* | ||
691 | * output given char | ||
692 | */ | ||
693 | static void bcm_console_putchar(struct uart_port *port, int ch) | ||
694 | { | ||
695 | wait_for_xmitr(port); | ||
696 | bcm_uart_writel(port, ch, UART_FIFO_REG); | ||
697 | } | ||
698 | |||
699 | /* | ||
700 | * console core request to output given string | ||
701 | */ | ||
702 | static void bcm_console_write(struct console *co, const char *s, | ||
703 | unsigned int count) | ||
704 | { | ||
705 | struct uart_port *port; | ||
706 | unsigned long flags; | ||
707 | int locked; | ||
708 | |||
709 | port = &ports[co->index]; | ||
710 | |||
711 | local_irq_save(flags); | ||
712 | if (port->sysrq) { | ||
713 | /* bcm_uart_interrupt() already took the lock */ | ||
714 | locked = 0; | ||
715 | } else if (oops_in_progress) { | ||
716 | locked = spin_trylock(&port->lock); | ||
717 | } else { | ||
718 | spin_lock(&port->lock); | ||
719 | locked = 1; | ||
720 | } | ||
721 | |||
722 | /* call helper to deal with \r\n */ | ||
723 | uart_console_write(port, s, count, bcm_console_putchar); | ||
724 | |||
725 | /* and wait for char to be transmitted */ | ||
726 | wait_for_xmitr(port); | ||
727 | |||
728 | if (locked) | ||
729 | spin_unlock(&port->lock); | ||
730 | local_irq_restore(flags); | ||
731 | } | ||
732 | |||
733 | /* | ||
734 | * console core request to setup given console, find matching uart | ||
735 | * port and setup it. | ||
736 | */ | ||
737 | static int bcm_console_setup(struct console *co, char *options) | ||
738 | { | ||
739 | struct uart_port *port; | ||
740 | int baud = 9600; | ||
741 | int bits = 8; | ||
742 | int parity = 'n'; | ||
743 | int flow = 'n'; | ||
744 | |||
745 | if (co->index < 0 || co->index >= BCM63XX_NR_UARTS) | ||
746 | return -EINVAL; | ||
747 | port = &ports[co->index]; | ||
748 | if (!port->membase) | ||
749 | return -ENODEV; | ||
750 | if (options) | ||
751 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
752 | |||
753 | return uart_set_options(port, co, baud, parity, bits, flow); | ||
754 | } | ||
755 | |||
756 | static struct uart_driver bcm_uart_driver; | ||
757 | |||
758 | static struct console bcm63xx_console = { | ||
759 | .name = "ttyS", | ||
760 | .write = bcm_console_write, | ||
761 | .device = uart_console_device, | ||
762 | .setup = bcm_console_setup, | ||
763 | .flags = CON_PRINTBUFFER, | ||
764 | .index = -1, | ||
765 | .data = &bcm_uart_driver, | ||
766 | }; | ||
767 | |||
768 | static int __init bcm63xx_console_init(void) | ||
769 | { | ||
770 | register_console(&bcm63xx_console); | ||
771 | return 0; | ||
772 | } | ||
773 | |||
774 | console_initcall(bcm63xx_console_init); | ||
775 | |||
776 | #define BCM63XX_CONSOLE (&bcm63xx_console) | ||
777 | #else | ||
778 | #define BCM63XX_CONSOLE NULL | ||
779 | #endif /* CONFIG_SERIAL_BCM63XX_CONSOLE */ | ||
780 | |||
781 | static struct uart_driver bcm_uart_driver = { | ||
782 | .owner = THIS_MODULE, | ||
783 | .driver_name = "bcm63xx_uart", | ||
784 | .dev_name = "ttyS", | ||
785 | .major = TTY_MAJOR, | ||
786 | .minor = 64, | ||
787 | .nr = BCM63XX_NR_UARTS, | ||
788 | .cons = BCM63XX_CONSOLE, | ||
789 | }; | ||
790 | |||
791 | /* | ||
792 | * platform driver probe/remove callback | ||
793 | */ | ||
794 | static int __devinit bcm_uart_probe(struct platform_device *pdev) | ||
795 | { | ||
796 | struct resource *res_mem, *res_irq; | ||
797 | struct uart_port *port; | ||
798 | struct clk *clk; | ||
799 | int ret; | ||
800 | |||
801 | if (pdev->id < 0 || pdev->id >= BCM63XX_NR_UARTS) | ||
802 | return -EINVAL; | ||
803 | |||
804 | if (ports[pdev->id].membase) | ||
805 | return -EBUSY; | ||
806 | |||
807 | res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
808 | if (!res_mem) | ||
809 | return -ENODEV; | ||
810 | |||
811 | res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
812 | if (!res_irq) | ||
813 | return -ENODEV; | ||
814 | |||
815 | clk = clk_get(&pdev->dev, "periph"); | ||
816 | if (IS_ERR(clk)) | ||
817 | return -ENODEV; | ||
818 | |||
819 | port = &ports[pdev->id]; | ||
820 | memset(port, 0, sizeof(*port)); | ||
821 | port->iotype = UPIO_MEM; | ||
822 | port->mapbase = res_mem->start; | ||
823 | port->irq = res_irq->start; | ||
824 | port->ops = &bcm_uart_ops; | ||
825 | port->flags = UPF_BOOT_AUTOCONF; | ||
826 | port->dev = &pdev->dev; | ||
827 | port->fifosize = 16; | ||
828 | port->uartclk = clk_get_rate(clk) / 2; | ||
829 | port->line = pdev->id; | ||
830 | clk_put(clk); | ||
831 | |||
832 | ret = uart_add_one_port(&bcm_uart_driver, port); | ||
833 | if (ret) { | ||
834 | ports[pdev->id].membase = 0; | ||
835 | return ret; | ||
836 | } | ||
837 | platform_set_drvdata(pdev, port); | ||
838 | return 0; | ||
839 | } | ||
840 | |||
841 | static int __devexit bcm_uart_remove(struct platform_device *pdev) | ||
842 | { | ||
843 | struct uart_port *port; | ||
844 | |||
845 | port = platform_get_drvdata(pdev); | ||
846 | uart_remove_one_port(&bcm_uart_driver, port); | ||
847 | platform_set_drvdata(pdev, NULL); | ||
848 | /* mark port as free */ | ||
849 | ports[pdev->id].membase = 0; | ||
850 | return 0; | ||
851 | } | ||
852 | |||
853 | /* | ||
854 | * platform driver stuff | ||
855 | */ | ||
856 | static struct platform_driver bcm_uart_platform_driver = { | ||
857 | .probe = bcm_uart_probe, | ||
858 | .remove = __devexit_p(bcm_uart_remove), | ||
859 | .driver = { | ||
860 | .owner = THIS_MODULE, | ||
861 | .name = "bcm63xx_uart", | ||
862 | }, | ||
863 | }; | ||
864 | |||
865 | static int __init bcm_uart_init(void) | ||
866 | { | ||
867 | int ret; | ||
868 | |||
869 | ret = uart_register_driver(&bcm_uart_driver); | ||
870 | if (ret) | ||
871 | return ret; | ||
872 | |||
873 | ret = platform_driver_register(&bcm_uart_platform_driver); | ||
874 | if (ret) | ||
875 | uart_unregister_driver(&bcm_uart_driver); | ||
876 | |||
877 | return ret; | ||
878 | } | ||
879 | |||
880 | static void __exit bcm_uart_exit(void) | ||
881 | { | ||
882 | platform_driver_unregister(&bcm_uart_platform_driver); | ||
883 | uart_unregister_driver(&bcm_uart_driver); | ||
884 | } | ||
885 | |||
886 | module_init(bcm_uart_init); | ||
887 | module_exit(bcm_uart_exit); | ||
888 | |||
889 | MODULE_AUTHOR("Maxime Bizon <mbizon@freebox.fr>"); | ||
890 | MODULE_DESCRIPTION("Broadcom 63<xx integrated uart driver"); | ||
891 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index b4a7650af696..e381b895b04d 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Blackfin On-Chip Serial Driver | 2 | * Blackfin On-Chip Serial Driver |
3 | * | 3 | * |
4 | * Copyright 2006-2008 Analog Devices Inc. | 4 | * Copyright 2006-2010 Analog Devices Inc. |
5 | * | 5 | * |
6 | * Enter bugs at http://blackfin.uclinux.org/ | 6 | * Enter bugs at http://blackfin.uclinux.org/ |
7 | * | 7 | * |
@@ -12,8 +12,13 @@ | |||
12 | #define SUPPORT_SYSRQ | 12 | #define SUPPORT_SYSRQ |
13 | #endif | 13 | #endif |
14 | 14 | ||
15 | #define DRIVER_NAME "bfin-uart" | ||
16 | #define pr_fmt(fmt) DRIVER_NAME ": " fmt | ||
17 | |||
15 | #include <linux/module.h> | 18 | #include <linux/module.h> |
16 | #include <linux/ioport.h> | 19 | #include <linux/ioport.h> |
20 | #include <linux/gfp.h> | ||
21 | #include <linux/io.h> | ||
17 | #include <linux/init.h> | 22 | #include <linux/init.h> |
18 | #include <linux/console.h> | 23 | #include <linux/console.h> |
19 | #include <linux/sysrq.h> | 24 | #include <linux/sysrq.h> |
@@ -21,21 +26,23 @@ | |||
21 | #include <linux/tty.h> | 26 | #include <linux/tty.h> |
22 | #include <linux/tty_flip.h> | 27 | #include <linux/tty_flip.h> |
23 | #include <linux/serial_core.h> | 28 | #include <linux/serial_core.h> |
24 | 29 | #include <linux/gpio.h> | |
25 | #if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \ | 30 | #include <linux/irq.h> |
26 | defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE) | ||
27 | #include <linux/kgdb.h> | 31 | #include <linux/kgdb.h> |
28 | #include <asm/irq_regs.h> | 32 | #include <linux/slab.h> |
29 | #endif | ||
30 | |||
31 | #include <asm/gpio.h> | ||
32 | #include <mach/bfin_serial_5xx.h> | ||
33 | |||
34 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
35 | #include <linux/dma-mapping.h> | 33 | #include <linux/dma-mapping.h> |
36 | #include <asm/io.h> | 34 | |
37 | #include <asm/irq.h> | 35 | #include <asm/portmux.h> |
38 | #include <asm/cacheflush.h> | 36 | #include <asm/cacheflush.h> |
37 | #include <asm/dma.h> | ||
38 | |||
39 | #define port_membase(uart) (((struct bfin_serial_port *)(uart))->port.membase) | ||
40 | #define get_lsr_cache(uart) (((struct bfin_serial_port *)(uart))->lsr) | ||
41 | #define put_lsr_cache(uart, v) (((struct bfin_serial_port *)(uart))->lsr = (v)) | ||
42 | #include <asm/bfin_serial.h> | ||
43 | |||
44 | #ifdef CONFIG_SERIAL_BFIN_MODULE | ||
45 | # undef CONFIG_EARLY_PRINTK | ||
39 | #endif | 46 | #endif |
40 | 47 | ||
41 | #ifdef CONFIG_SERIAL_BFIN_MODULE | 48 | #ifdef CONFIG_SERIAL_BFIN_MODULE |
@@ -43,12 +50,11 @@ | |||
43 | #endif | 50 | #endif |
44 | 51 | ||
45 | /* UART name and device definitions */ | 52 | /* UART name and device definitions */ |
46 | #define BFIN_SERIAL_NAME "ttyBF" | 53 | #define BFIN_SERIAL_DEV_NAME "ttyBF" |
47 | #define BFIN_SERIAL_MAJOR 204 | 54 | #define BFIN_SERIAL_MAJOR 204 |
48 | #define BFIN_SERIAL_MINOR 64 | 55 | #define BFIN_SERIAL_MINOR 64 |
49 | 56 | ||
50 | static struct bfin_serial_port bfin_serial_ports[BFIN_UART_NR_PORTS]; | 57 | static struct bfin_serial_port *bfin_serial_ports[BFIN_UART_NR_PORTS]; |
51 | static int nr_active_ports = ARRAY_SIZE(bfin_serial_resource); | ||
52 | 58 | ||
53 | #if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \ | 59 | #if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \ |
54 | defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE) | 60 | defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE) |
@@ -140,7 +146,7 @@ static void bfin_serial_stop_tx(struct uart_port *port) | |||
140 | { | 146 | { |
141 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; | 147 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; |
142 | #ifdef CONFIG_SERIAL_BFIN_DMA | 148 | #ifdef CONFIG_SERIAL_BFIN_DMA |
143 | struct circ_buf *xmit = &uart->port.info->xmit; | 149 | struct circ_buf *xmit = &uart->port.state->xmit; |
144 | #endif | 150 | #endif |
145 | 151 | ||
146 | while (!(UART_GET_LSR(uart) & TEMT)) | 152 | while (!(UART_GET_LSR(uart) & TEMT)) |
@@ -167,7 +173,7 @@ static void bfin_serial_stop_tx(struct uart_port *port) | |||
167 | static void bfin_serial_start_tx(struct uart_port *port) | 173 | static void bfin_serial_start_tx(struct uart_port *port) |
168 | { | 174 | { |
169 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; | 175 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; |
170 | struct tty_struct *tty = uart->port.info->port.tty; | 176 | struct tty_struct *tty = uart->port.state->port.tty; |
171 | 177 | ||
172 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS | 178 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS |
173 | if (uart->scts && !(bfin_serial_get_mctrl(&uart->port) & TIOCM_CTS)) { | 179 | if (uart->scts && !(bfin_serial_get_mctrl(&uart->port) & TIOCM_CTS)) { |
@@ -233,16 +239,17 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart) | |||
233 | 239 | ||
234 | #if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \ | 240 | #if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \ |
235 | defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE) | 241 | defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE) |
236 | if (kgdb_connected && kgdboc_port_line == uart->port.line) | 242 | if (kgdb_connected && kgdboc_port_line == uart->port.line |
243 | && kgdboc_break_enabled) | ||
237 | if (ch == 0x3) {/* Ctrl + C */ | 244 | if (ch == 0x3) {/* Ctrl + C */ |
238 | kgdb_breakpoint(); | 245 | kgdb_breakpoint(); |
239 | return; | 246 | return; |
240 | } | 247 | } |
241 | 248 | ||
242 | if (!uart->port.info || !uart->port.info->port.tty) | 249 | if (!uart->port.state || !uart->port.state->port.tty) |
243 | return; | 250 | return; |
244 | #endif | 251 | #endif |
245 | tty = uart->port.info->port.tty; | 252 | tty = uart->port.state->port.tty; |
246 | 253 | ||
247 | if (ANOMALY_05000363) { | 254 | if (ANOMALY_05000363) { |
248 | /* The BF533 (and BF561) family of processors have a nice anomaly | 255 | /* The BF533 (and BF561) family of processors have a nice anomaly |
@@ -327,7 +334,7 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart) | |||
327 | 334 | ||
328 | static void bfin_serial_tx_chars(struct bfin_serial_port *uart) | 335 | static void bfin_serial_tx_chars(struct bfin_serial_port *uart) |
329 | { | 336 | { |
330 | struct circ_buf *xmit = &uart->port.info->xmit; | 337 | struct circ_buf *xmit = &uart->port.state->xmit; |
331 | 338 | ||
332 | if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) { | 339 | if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) { |
333 | #ifdef CONFIG_BF54x | 340 | #ifdef CONFIG_BF54x |
@@ -353,7 +360,6 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart) | |||
353 | UART_PUT_CHAR(uart, xmit->buf[xmit->tail]); | 360 | UART_PUT_CHAR(uart, xmit->buf[xmit->tail]); |
354 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | 361 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); |
355 | uart->port.icount.tx++; | 362 | uart->port.icount.tx++; |
356 | SSYNC(); | ||
357 | } | 363 | } |
358 | 364 | ||
359 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 365 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
@@ -394,7 +400,7 @@ static irqreturn_t bfin_serial_tx_int(int irq, void *dev_id) | |||
394 | #ifdef CONFIG_SERIAL_BFIN_DMA | 400 | #ifdef CONFIG_SERIAL_BFIN_DMA |
395 | static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart) | 401 | static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart) |
396 | { | 402 | { |
397 | struct circ_buf *xmit = &uart->port.info->xmit; | 403 | struct circ_buf *xmit = &uart->port.state->xmit; |
398 | 404 | ||
399 | uart->tx_done = 0; | 405 | uart->tx_done = 0; |
400 | 406 | ||
@@ -432,7 +438,7 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart) | |||
432 | 438 | ||
433 | static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) | 439 | static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) |
434 | { | 440 | { |
435 | struct tty_struct *tty = uart->port.info->port.tty; | 441 | struct tty_struct *tty = uart->port.state->port.tty; |
436 | int i, flg, status; | 442 | int i, flg, status; |
437 | 443 | ||
438 | status = UART_GET_LSR(uart); | 444 | status = UART_GET_LSR(uart); |
@@ -484,6 +490,7 @@ void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) | |||
484 | { | 490 | { |
485 | int x_pos, pos; | 491 | int x_pos, pos; |
486 | 492 | ||
493 | dma_disable_irq(uart->tx_dma_channel); | ||
487 | dma_disable_irq(uart->rx_dma_channel); | 494 | dma_disable_irq(uart->rx_dma_channel); |
488 | spin_lock_bh(&uart->port.lock); | 495 | spin_lock_bh(&uart->port.lock); |
489 | 496 | ||
@@ -517,6 +524,7 @@ void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) | |||
517 | } | 524 | } |
518 | 525 | ||
519 | spin_unlock_bh(&uart->port.lock); | 526 | spin_unlock_bh(&uart->port.lock); |
527 | dma_enable_irq(uart->tx_dma_channel); | ||
520 | dma_enable_irq(uart->rx_dma_channel); | 528 | dma_enable_irq(uart->rx_dma_channel); |
521 | 529 | ||
522 | mod_timer(&(uart->rx_dma_timer), jiffies + DMA_RX_FLUSH_JIFFIES); | 530 | mod_timer(&(uart->rx_dma_timer), jiffies + DMA_RX_FLUSH_JIFFIES); |
@@ -525,7 +533,7 @@ void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) | |||
525 | static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id) | 533 | static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id) |
526 | { | 534 | { |
527 | struct bfin_serial_port *uart = dev_id; | 535 | struct bfin_serial_port *uart = dev_id; |
528 | struct circ_buf *xmit = &uart->port.info->xmit; | 536 | struct circ_buf *xmit = &uart->port.state->xmit; |
529 | 537 | ||
530 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS | 538 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS |
531 | if (uart->scts && !(bfin_serial_get_mctrl(&uart->port)&TIOCM_CTS)) { | 539 | if (uart->scts && !(bfin_serial_get_mctrl(&uart->port)&TIOCM_CTS)) { |
@@ -679,6 +687,13 @@ static int bfin_serial_startup(struct uart_port *port) | |||
679 | 687 | ||
680 | # ifdef CONFIG_BF54x | 688 | # ifdef CONFIG_BF54x |
681 | { | 689 | { |
690 | /* | ||
691 | * UART2 and UART3 on BF548 share interrupt PINs and DMA | ||
692 | * controllers with SPORT2 and SPORT3. UART rx and tx | ||
693 | * interrupts are generated in PIO mode only when configure | ||
694 | * their peripheral mapping registers properly, which means | ||
695 | * request corresponding DMA channels in PIO mode as well. | ||
696 | */ | ||
682 | unsigned uart_dma_ch_rx, uart_dma_ch_tx; | 697 | unsigned uart_dma_ch_rx, uart_dma_ch_tx; |
683 | 698 | ||
684 | switch (uart->port.irq) { | 699 | switch (uart->port.irq) { |
@@ -725,30 +740,19 @@ static int bfin_serial_startup(struct uart_port *port) | |||
725 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | | 740 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | |
726 | IRQF_DISABLED, "BFIN_UART_CTS", uart)) { | 741 | IRQF_DISABLED, "BFIN_UART_CTS", uart)) { |
727 | uart->cts_pin = -1; | 742 | uart->cts_pin = -1; |
728 | pr_info("Unable to attach BlackFin UART CTS interrupt.\ | 743 | pr_info("Unable to attach BlackFin UART CTS interrupt. So, disable it.\n"); |
729 | So, disable it.\n"); | ||
730 | } | 744 | } |
731 | } | 745 | } |
732 | if (uart->rts_pin >= 0) { | 746 | if (uart->rts_pin >= 0) { |
733 | gpio_request(uart->rts_pin, DRIVER_NAME); | ||
734 | gpio_direction_output(uart->rts_pin, 0); | 747 | gpio_direction_output(uart->rts_pin, 0); |
735 | } | 748 | } |
736 | #endif | 749 | #endif |
737 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS | 750 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS |
738 | if (request_irq(uart->status_irq, | 751 | if (uart->cts_pin >= 0 && request_irq(uart->status_irq, |
739 | bfin_serial_mctrl_cts_int, | 752 | bfin_serial_mctrl_cts_int, |
740 | IRQF_DISABLED, "BFIN_UART_MODEM_STATUS", uart)) { | 753 | IRQF_DISABLED, "BFIN_UART_MODEM_STATUS", uart)) { |
741 | pr_info("Unable to attach BlackFin UART Modem \ | 754 | uart->cts_pin = -1; |
742 | Status interrupt.\n"); | 755 | pr_info("Unable to attach BlackFin UART Modem Status interrupt.\n"); |
743 | } | ||
744 | |||
745 | if (uart->cts_pin >= 0) { | ||
746 | gpio_request(uart->cts_pin, DRIVER_NAME); | ||
747 | gpio_direction_output(uart->cts_pin, 1); | ||
748 | } | ||
749 | if (uart->rts_pin >= 0) { | ||
750 | gpio_request(uart->rts_pin, DRIVER_NAME); | ||
751 | gpio_direction_output(uart->rts_pin, 0); | ||
752 | } | 756 | } |
753 | 757 | ||
754 | /* CTS RTS PINs are negative assertive. */ | 758 | /* CTS RTS PINs are negative assertive. */ |
@@ -793,15 +797,9 @@ static void bfin_serial_shutdown(struct uart_port *port) | |||
793 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | 797 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS |
794 | if (uart->cts_pin >= 0) | 798 | if (uart->cts_pin >= 0) |
795 | free_irq(gpio_to_irq(uart->cts_pin), uart); | 799 | free_irq(gpio_to_irq(uart->cts_pin), uart); |
796 | if (uart->rts_pin >= 0) | ||
797 | gpio_free(uart->rts_pin); | ||
798 | #endif | 800 | #endif |
799 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS | 801 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS |
800 | if (uart->cts_pin >= 0) | 802 | if (uart->cts_pin >= 0) |
801 | gpio_free(uart->cts_pin); | ||
802 | if (uart->rts_pin >= 0) | ||
803 | gpio_free(uart->rts_pin); | ||
804 | if (UART_GET_IER(uart) && EDSSI) | ||
805 | free_irq(uart->status_irq, uart); | 803 | free_irq(uart->status_irq, uart); |
806 | #endif | 804 | #endif |
807 | } | 805 | } |
@@ -850,6 +848,8 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios, | |||
850 | if (termios->c_cflag & CMSPAR) | 848 | if (termios->c_cflag & CMSPAR) |
851 | lcr |= STP; | 849 | lcr |= STP; |
852 | 850 | ||
851 | spin_lock_irqsave(&uart->port.lock, flags); | ||
852 | |||
853 | port->read_status_mask = OE; | 853 | port->read_status_mask = OE; |
854 | if (termios->c_iflag & INPCK) | 854 | if (termios->c_iflag & INPCK) |
855 | port->read_status_mask |= (FE | PE); | 855 | port->read_status_mask |= (FE | PE); |
@@ -873,8 +873,11 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios, | |||
873 | } | 873 | } |
874 | 874 | ||
875 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); | 875 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); |
876 | quot = uart_get_divisor(port, baud) - ANOMALY_05000230; | 876 | quot = uart_get_divisor(port, baud); |
877 | spin_lock_irqsave(&uart->port.lock, flags); | 877 | |
878 | /* If discipline is not IRDA, apply ANOMALY_05000230 */ | ||
879 | if (termios->c_line != N_IRDA) | ||
880 | quot -= ANOMALY_05000230; | ||
878 | 881 | ||
879 | UART_SET_ANOMALY_THRESHOLD(uart, USEC_PER_SEC / baud * 15); | 882 | UART_SET_ANOMALY_THRESHOLD(uart, USEC_PER_SEC / baud * 15); |
880 | 883 | ||
@@ -956,38 +959,35 @@ bfin_serial_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
956 | * Enable the IrDA function if tty->ldisc.num is N_IRDA. | 959 | * Enable the IrDA function if tty->ldisc.num is N_IRDA. |
957 | * In other cases, disable IrDA function. | 960 | * In other cases, disable IrDA function. |
958 | */ | 961 | */ |
959 | static void bfin_serial_set_ldisc(struct uart_port *port) | 962 | static void bfin_serial_set_ldisc(struct uart_port *port, int ld) |
960 | { | 963 | { |
961 | int line = port->line; | 964 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; |
962 | unsigned short val; | 965 | unsigned short val; |
963 | 966 | ||
964 | if (line >= port->info->port.tty->driver->num) | 967 | switch (ld) { |
965 | return; | ||
966 | |||
967 | switch (port->info->port.tty->termios->c_line) { | ||
968 | case N_IRDA: | 968 | case N_IRDA: |
969 | val = UART_GET_GCTL(&bfin_serial_ports[line]); | 969 | val = UART_GET_GCTL(uart); |
970 | val |= (IREN | RPOLC); | 970 | val |= (IREN | RPOLC); |
971 | UART_PUT_GCTL(&bfin_serial_ports[line], val); | 971 | UART_PUT_GCTL(uart, val); |
972 | break; | 972 | break; |
973 | default: | 973 | default: |
974 | val = UART_GET_GCTL(&bfin_serial_ports[line]); | 974 | val = UART_GET_GCTL(uart); |
975 | val &= ~(IREN | RPOLC); | 975 | val &= ~(IREN | RPOLC); |
976 | UART_PUT_GCTL(&bfin_serial_ports[line], val); | 976 | UART_PUT_GCTL(uart, val); |
977 | } | 977 | } |
978 | } | 978 | } |
979 | 979 | ||
980 | static void bfin_serial_reset_irda(struct uart_port *port) | 980 | static void bfin_serial_reset_irda(struct uart_port *port) |
981 | { | 981 | { |
982 | int line = port->line; | 982 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; |
983 | unsigned short val; | 983 | unsigned short val; |
984 | 984 | ||
985 | val = UART_GET_GCTL(&bfin_serial_ports[line]); | 985 | val = UART_GET_GCTL(uart); |
986 | val &= ~(IREN | RPOLC); | 986 | val &= ~(IREN | RPOLC); |
987 | UART_PUT_GCTL(&bfin_serial_ports[line], val); | 987 | UART_PUT_GCTL(uart, val); |
988 | SSYNC(); | 988 | SSYNC(); |
989 | val |= (IREN | RPOLC); | 989 | val |= (IREN | RPOLC); |
990 | UART_PUT_GCTL(&bfin_serial_ports[line], val); | 990 | UART_PUT_GCTL(uart, val); |
991 | SSYNC(); | 991 | SSYNC(); |
992 | } | 992 | } |
993 | 993 | ||
@@ -1069,85 +1069,6 @@ static struct uart_ops bfin_serial_pops = { | |||
1069 | #endif | 1069 | #endif |
1070 | }; | 1070 | }; |
1071 | 1071 | ||
1072 | static void __init bfin_serial_hw_init(void) | ||
1073 | { | ||
1074 | #ifdef CONFIG_SERIAL_BFIN_UART0 | ||
1075 | peripheral_request(P_UART0_TX, DRIVER_NAME); | ||
1076 | peripheral_request(P_UART0_RX, DRIVER_NAME); | ||
1077 | #endif | ||
1078 | |||
1079 | #ifdef CONFIG_SERIAL_BFIN_UART1 | ||
1080 | peripheral_request(P_UART1_TX, DRIVER_NAME); | ||
1081 | peripheral_request(P_UART1_RX, DRIVER_NAME); | ||
1082 | |||
1083 | # if defined(CONFIG_BFIN_UART1_CTSRTS) && defined(CONFIG_BF54x) | ||
1084 | peripheral_request(P_UART1_RTS, DRIVER_NAME); | ||
1085 | peripheral_request(P_UART1_CTS, DRIVER_NAME); | ||
1086 | # endif | ||
1087 | #endif | ||
1088 | |||
1089 | #ifdef CONFIG_SERIAL_BFIN_UART2 | ||
1090 | peripheral_request(P_UART2_TX, DRIVER_NAME); | ||
1091 | peripheral_request(P_UART2_RX, DRIVER_NAME); | ||
1092 | #endif | ||
1093 | |||
1094 | #ifdef CONFIG_SERIAL_BFIN_UART3 | ||
1095 | peripheral_request(P_UART3_TX, DRIVER_NAME); | ||
1096 | peripheral_request(P_UART3_RX, DRIVER_NAME); | ||
1097 | |||
1098 | # if defined(CONFIG_BFIN_UART3_CTSRTS) && defined(CONFIG_BF54x) | ||
1099 | peripheral_request(P_UART3_RTS, DRIVER_NAME); | ||
1100 | peripheral_request(P_UART3_CTS, DRIVER_NAME); | ||
1101 | # endif | ||
1102 | #endif | ||
1103 | } | ||
1104 | |||
1105 | static void __init bfin_serial_init_ports(void) | ||
1106 | { | ||
1107 | static int first = 1; | ||
1108 | int i; | ||
1109 | |||
1110 | if (!first) | ||
1111 | return; | ||
1112 | first = 0; | ||
1113 | |||
1114 | bfin_serial_hw_init(); | ||
1115 | |||
1116 | for (i = 0; i < nr_active_ports; i++) { | ||
1117 | spin_lock_init(&bfin_serial_ports[i].port.lock); | ||
1118 | bfin_serial_ports[i].port.uartclk = get_sclk(); | ||
1119 | bfin_serial_ports[i].port.fifosize = BFIN_UART_TX_FIFO_SIZE; | ||
1120 | bfin_serial_ports[i].port.ops = &bfin_serial_pops; | ||
1121 | bfin_serial_ports[i].port.line = i; | ||
1122 | bfin_serial_ports[i].port.iotype = UPIO_MEM; | ||
1123 | bfin_serial_ports[i].port.membase = | ||
1124 | (void __iomem *)bfin_serial_resource[i].uart_base_addr; | ||
1125 | bfin_serial_ports[i].port.mapbase = | ||
1126 | bfin_serial_resource[i].uart_base_addr; | ||
1127 | bfin_serial_ports[i].port.irq = | ||
1128 | bfin_serial_resource[i].uart_irq; | ||
1129 | bfin_serial_ports[i].status_irq = | ||
1130 | bfin_serial_resource[i].uart_status_irq; | ||
1131 | bfin_serial_ports[i].port.flags = UPF_BOOT_AUTOCONF; | ||
1132 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
1133 | bfin_serial_ports[i].tx_done = 1; | ||
1134 | bfin_serial_ports[i].tx_count = 0; | ||
1135 | bfin_serial_ports[i].tx_dma_channel = | ||
1136 | bfin_serial_resource[i].uart_tx_dma_channel; | ||
1137 | bfin_serial_ports[i].rx_dma_channel = | ||
1138 | bfin_serial_resource[i].uart_rx_dma_channel; | ||
1139 | init_timer(&(bfin_serial_ports[i].rx_dma_timer)); | ||
1140 | #endif | ||
1141 | #if defined(CONFIG_SERIAL_BFIN_CTSRTS) || \ | ||
1142 | defined(CONFIG_SERIAL_BFIN_HARD_CTSRTS) | ||
1143 | bfin_serial_ports[i].cts_pin = | ||
1144 | bfin_serial_resource[i].uart_cts_pin; | ||
1145 | bfin_serial_ports[i].rts_pin = | ||
1146 | bfin_serial_resource[i].uart_rts_pin; | ||
1147 | #endif | ||
1148 | } | ||
1149 | } | ||
1150 | |||
1151 | #if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) | 1072 | #if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) |
1152 | /* | 1073 | /* |
1153 | * If the port was already initialised (eg, by a boot loader), | 1074 | * If the port was already initialised (eg, by a boot loader), |
@@ -1195,6 +1116,34 @@ bfin_serial_console_get_options(struct bfin_serial_port *uart, int *baud, | |||
1195 | 1116 | ||
1196 | static struct uart_driver bfin_serial_reg; | 1117 | static struct uart_driver bfin_serial_reg; |
1197 | 1118 | ||
1119 | static void bfin_serial_console_putchar(struct uart_port *port, int ch) | ||
1120 | { | ||
1121 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; | ||
1122 | while (!(UART_GET_LSR(uart) & THRE)) | ||
1123 | barrier(); | ||
1124 | UART_PUT_CHAR(uart, ch); | ||
1125 | } | ||
1126 | |||
1127 | #endif /* defined (CONFIG_SERIAL_BFIN_CONSOLE) || | ||
1128 | defined (CONFIG_EARLY_PRINTK) */ | ||
1129 | |||
1130 | #ifdef CONFIG_SERIAL_BFIN_CONSOLE | ||
1131 | #define CLASS_BFIN_CONSOLE "bfin-console" | ||
1132 | /* | ||
1133 | * Interrupts are disabled on entering | ||
1134 | */ | ||
1135 | static void | ||
1136 | bfin_serial_console_write(struct console *co, const char *s, unsigned int count) | ||
1137 | { | ||
1138 | struct bfin_serial_port *uart = bfin_serial_ports[co->index]; | ||
1139 | unsigned long flags; | ||
1140 | |||
1141 | spin_lock_irqsave(&uart->port.lock, flags); | ||
1142 | uart_console_write(&uart->port, s, count, bfin_serial_console_putchar); | ||
1143 | spin_unlock_irqrestore(&uart->port.lock, flags); | ||
1144 | |||
1145 | } | ||
1146 | |||
1198 | static int __init | 1147 | static int __init |
1199 | bfin_serial_console_setup(struct console *co, char *options) | 1148 | bfin_serial_console_setup(struct console *co, char *options) |
1200 | { | 1149 | { |
@@ -1214,9 +1163,12 @@ bfin_serial_console_setup(struct console *co, char *options) | |||
1214 | * if so, search for the first available port that does have | 1163 | * if so, search for the first available port that does have |
1215 | * console support. | 1164 | * console support. |
1216 | */ | 1165 | */ |
1217 | if (co->index == -1 || co->index >= nr_active_ports) | 1166 | if (co->index < 0 || co->index >= BFIN_UART_NR_PORTS) |
1218 | co->index = 0; | 1167 | return -ENODEV; |
1219 | uart = &bfin_serial_ports[co->index]; | 1168 | |
1169 | uart = bfin_serial_ports[co->index]; | ||
1170 | if (!uart) | ||
1171 | return -ENODEV; | ||
1220 | 1172 | ||
1221 | if (options) | 1173 | if (options) |
1222 | uart_parse_options(options, &baud, &parity, &bits, &flow); | 1174 | uart_parse_options(options, &baud, &parity, &bits, &flow); |
@@ -1225,36 +1177,9 @@ bfin_serial_console_setup(struct console *co, char *options) | |||
1225 | 1177 | ||
1226 | return uart_set_options(&uart->port, co, baud, parity, bits, flow); | 1178 | return uart_set_options(&uart->port, co, baud, parity, bits, flow); |
1227 | } | 1179 | } |
1228 | #endif /* defined (CONFIG_SERIAL_BFIN_CONSOLE) || | ||
1229 | defined (CONFIG_EARLY_PRINTK) */ | ||
1230 | |||
1231 | #ifdef CONFIG_SERIAL_BFIN_CONSOLE | ||
1232 | static void bfin_serial_console_putchar(struct uart_port *port, int ch) | ||
1233 | { | ||
1234 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; | ||
1235 | while (!(UART_GET_LSR(uart) & THRE)) | ||
1236 | barrier(); | ||
1237 | UART_PUT_CHAR(uart, ch); | ||
1238 | SSYNC(); | ||
1239 | } | ||
1240 | |||
1241 | /* | ||
1242 | * Interrupts are disabled on entering | ||
1243 | */ | ||
1244 | static void | ||
1245 | bfin_serial_console_write(struct console *co, const char *s, unsigned int count) | ||
1246 | { | ||
1247 | struct bfin_serial_port *uart = &bfin_serial_ports[co->index]; | ||
1248 | unsigned long flags; | ||
1249 | |||
1250 | spin_lock_irqsave(&uart->port.lock, flags); | ||
1251 | uart_console_write(&uart->port, s, count, bfin_serial_console_putchar); | ||
1252 | spin_unlock_irqrestore(&uart->port.lock, flags); | ||
1253 | |||
1254 | } | ||
1255 | 1180 | ||
1256 | static struct console bfin_serial_console = { | 1181 | static struct console bfin_serial_console = { |
1257 | .name = BFIN_SERIAL_NAME, | 1182 | .name = BFIN_SERIAL_DEV_NAME, |
1258 | .write = bfin_serial_console_write, | 1183 | .write = bfin_serial_console_write, |
1259 | .device = uart_console_device, | 1184 | .device = uart_console_device, |
1260 | .setup = bfin_serial_console_setup, | 1185 | .setup = bfin_serial_console_setup, |
@@ -1262,44 +1187,30 @@ static struct console bfin_serial_console = { | |||
1262 | .index = -1, | 1187 | .index = -1, |
1263 | .data = &bfin_serial_reg, | 1188 | .data = &bfin_serial_reg, |
1264 | }; | 1189 | }; |
1265 | |||
1266 | static int __init bfin_serial_rs_console_init(void) | ||
1267 | { | ||
1268 | bfin_serial_init_ports(); | ||
1269 | register_console(&bfin_serial_console); | ||
1270 | |||
1271 | return 0; | ||
1272 | } | ||
1273 | console_initcall(bfin_serial_rs_console_init); | ||
1274 | |||
1275 | #define BFIN_SERIAL_CONSOLE &bfin_serial_console | 1190 | #define BFIN_SERIAL_CONSOLE &bfin_serial_console |
1276 | #else | 1191 | #else |
1277 | #define BFIN_SERIAL_CONSOLE NULL | 1192 | #define BFIN_SERIAL_CONSOLE NULL |
1278 | #endif /* CONFIG_SERIAL_BFIN_CONSOLE */ | 1193 | #endif /* CONFIG_SERIAL_BFIN_CONSOLE */ |
1279 | 1194 | ||
1195 | #ifdef CONFIG_EARLY_PRINTK | ||
1196 | static struct bfin_serial_port bfin_earlyprintk_port; | ||
1197 | #define CLASS_BFIN_EARLYPRINTK "bfin-earlyprintk" | ||
1280 | 1198 | ||
1281 | #ifdef CONFIG_EARLY_PRINTK | 1199 | /* |
1282 | static __init void early_serial_putc(struct uart_port *port, int ch) | 1200 | * Interrupts are disabled on entering |
1201 | */ | ||
1202 | static void | ||
1203 | bfin_earlyprintk_console_write(struct console *co, const char *s, unsigned int count) | ||
1283 | { | 1204 | { |
1284 | unsigned timeout = 0xffff; | 1205 | unsigned long flags; |
1285 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; | ||
1286 | |||
1287 | while ((!(UART_GET_LSR(uart) & THRE)) && --timeout) | ||
1288 | cpu_relax(); | ||
1289 | UART_PUT_CHAR(uart, ch); | ||
1290 | } | ||
1291 | 1206 | ||
1292 | static __init void early_serial_write(struct console *con, const char *s, | 1207 | if (bfin_earlyprintk_port.port.line != co->index) |
1293 | unsigned int n) | 1208 | return; |
1294 | { | ||
1295 | struct bfin_serial_port *uart = &bfin_serial_ports[con->index]; | ||
1296 | unsigned int i; | ||
1297 | 1209 | ||
1298 | for (i = 0; i < n; i++, s++) { | 1210 | spin_lock_irqsave(&bfin_earlyprintk_port.port.lock, flags); |
1299 | if (*s == '\n') | 1211 | uart_console_write(&bfin_earlyprintk_port.port, s, count, |
1300 | early_serial_putc(&uart->port, '\r'); | 1212 | bfin_serial_console_putchar); |
1301 | early_serial_putc(&uart->port, *s); | 1213 | spin_unlock_irqrestore(&bfin_earlyprintk_port.port.lock, flags); |
1302 | } | ||
1303 | } | 1214 | } |
1304 | 1215 | ||
1305 | /* | 1216 | /* |
@@ -1310,106 +1221,204 @@ static __init void early_serial_write(struct console *con, const char *s, | |||
1310 | */ | 1221 | */ |
1311 | static struct __initdata console bfin_early_serial_console = { | 1222 | static struct __initdata console bfin_early_serial_console = { |
1312 | .name = "early_BFuart", | 1223 | .name = "early_BFuart", |
1313 | .write = early_serial_write, | 1224 | .write = bfin_earlyprintk_console_write, |
1314 | .device = uart_console_device, | 1225 | .device = uart_console_device, |
1315 | .flags = CON_PRINTBUFFER, | 1226 | .flags = CON_PRINTBUFFER, |
1316 | .index = -1, | 1227 | .index = -1, |
1317 | .data = &bfin_serial_reg, | 1228 | .data = &bfin_serial_reg, |
1318 | }; | 1229 | }; |
1319 | 1230 | #endif | |
1320 | struct console __init *bfin_earlyserial_init(unsigned int port, | ||
1321 | unsigned int cflag) | ||
1322 | { | ||
1323 | struct bfin_serial_port *uart; | ||
1324 | struct ktermios t; | ||
1325 | |||
1326 | if (port == -1 || port >= nr_active_ports) | ||
1327 | port = 0; | ||
1328 | bfin_serial_init_ports(); | ||
1329 | bfin_early_serial_console.index = port; | ||
1330 | uart = &bfin_serial_ports[port]; | ||
1331 | t.c_cflag = cflag; | ||
1332 | t.c_iflag = 0; | ||
1333 | t.c_oflag = 0; | ||
1334 | t.c_lflag = ICANON; | ||
1335 | t.c_line = port; | ||
1336 | bfin_serial_set_termios(&uart->port, &t, &t); | ||
1337 | return &bfin_early_serial_console; | ||
1338 | } | ||
1339 | |||
1340 | #endif /* CONFIG_EARLY_PRINTK */ | ||
1341 | 1231 | ||
1342 | static struct uart_driver bfin_serial_reg = { | 1232 | static struct uart_driver bfin_serial_reg = { |
1343 | .owner = THIS_MODULE, | 1233 | .owner = THIS_MODULE, |
1344 | .driver_name = "bfin-uart", | 1234 | .driver_name = DRIVER_NAME, |
1345 | .dev_name = BFIN_SERIAL_NAME, | 1235 | .dev_name = BFIN_SERIAL_DEV_NAME, |
1346 | .major = BFIN_SERIAL_MAJOR, | 1236 | .major = BFIN_SERIAL_MAJOR, |
1347 | .minor = BFIN_SERIAL_MINOR, | 1237 | .minor = BFIN_SERIAL_MINOR, |
1348 | .nr = BFIN_UART_NR_PORTS, | 1238 | .nr = BFIN_UART_NR_PORTS, |
1349 | .cons = BFIN_SERIAL_CONSOLE, | 1239 | .cons = BFIN_SERIAL_CONSOLE, |
1350 | }; | 1240 | }; |
1351 | 1241 | ||
1352 | static int bfin_serial_suspend(struct platform_device *dev, pm_message_t state) | 1242 | static int bfin_serial_suspend(struct platform_device *pdev, pm_message_t state) |
1353 | { | 1243 | { |
1354 | int i; | 1244 | struct bfin_serial_port *uart = platform_get_drvdata(pdev); |
1355 | 1245 | ||
1356 | for (i = 0; i < nr_active_ports; i++) { | 1246 | return uart_suspend_port(&bfin_serial_reg, &uart->port); |
1357 | if (bfin_serial_ports[i].port.dev != &dev->dev) | 1247 | } |
1358 | continue; | ||
1359 | uart_suspend_port(&bfin_serial_reg, &bfin_serial_ports[i].port); | ||
1360 | } | ||
1361 | 1248 | ||
1362 | return 0; | 1249 | static int bfin_serial_resume(struct platform_device *pdev) |
1250 | { | ||
1251 | struct bfin_serial_port *uart = platform_get_drvdata(pdev); | ||
1252 | |||
1253 | return uart_resume_port(&bfin_serial_reg, &uart->port); | ||
1363 | } | 1254 | } |
1364 | 1255 | ||
1365 | static int bfin_serial_resume(struct platform_device *dev) | 1256 | static int bfin_serial_probe(struct platform_device *pdev) |
1366 | { | 1257 | { |
1367 | int i; | 1258 | struct resource *res; |
1259 | struct bfin_serial_port *uart = NULL; | ||
1260 | int ret = 0; | ||
1368 | 1261 | ||
1369 | for (i = 0; i < nr_active_ports; i++) { | 1262 | if (pdev->id < 0 || pdev->id >= BFIN_UART_NR_PORTS) { |
1370 | if (bfin_serial_ports[i].port.dev != &dev->dev) | 1263 | dev_err(&pdev->dev, "Wrong bfin uart platform device id.\n"); |
1371 | continue; | 1264 | return -ENOENT; |
1372 | uart_resume_port(&bfin_serial_reg, &bfin_serial_ports[i].port); | ||
1373 | } | 1265 | } |
1374 | 1266 | ||
1375 | return 0; | 1267 | if (bfin_serial_ports[pdev->id] == NULL) { |
1376 | } | ||
1377 | 1268 | ||
1378 | static int bfin_serial_probe(struct platform_device *dev) | 1269 | uart = kzalloc(sizeof(*uart), GFP_KERNEL); |
1379 | { | 1270 | if (!uart) { |
1380 | struct resource *res = dev->resource; | 1271 | dev_err(&pdev->dev, |
1381 | int i; | 1272 | "fail to malloc bfin_serial_port\n"); |
1273 | return -ENOMEM; | ||
1274 | } | ||
1275 | bfin_serial_ports[pdev->id] = uart; | ||
1382 | 1276 | ||
1383 | for (i = 0; i < dev->num_resources; i++, res++) | 1277 | #ifdef CONFIG_EARLY_PRINTK |
1384 | if (res->flags & IORESOURCE_MEM) | 1278 | if (!(bfin_earlyprintk_port.port.membase |
1385 | break; | 1279 | && bfin_earlyprintk_port.port.line == pdev->id)) { |
1280 | /* | ||
1281 | * If the peripheral PINs of current port is allocated | ||
1282 | * in earlyprintk probe stage, don't do it again. | ||
1283 | */ | ||
1284 | #endif | ||
1285 | ret = peripheral_request_list( | ||
1286 | (unsigned short *)pdev->dev.platform_data, DRIVER_NAME); | ||
1287 | if (ret) { | ||
1288 | dev_err(&pdev->dev, | ||
1289 | "fail to request bfin serial peripherals\n"); | ||
1290 | goto out_error_free_mem; | ||
1291 | } | ||
1292 | #ifdef CONFIG_EARLY_PRINTK | ||
1293 | } | ||
1294 | #endif | ||
1295 | |||
1296 | spin_lock_init(&uart->port.lock); | ||
1297 | uart->port.uartclk = get_sclk(); | ||
1298 | uart->port.fifosize = BFIN_UART_TX_FIFO_SIZE; | ||
1299 | uart->port.ops = &bfin_serial_pops; | ||
1300 | uart->port.line = pdev->id; | ||
1301 | uart->port.iotype = UPIO_MEM; | ||
1302 | uart->port.flags = UPF_BOOT_AUTOCONF; | ||
1303 | |||
1304 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1305 | if (res == NULL) { | ||
1306 | dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n"); | ||
1307 | ret = -ENOENT; | ||
1308 | goto out_error_free_peripherals; | ||
1309 | } | ||
1310 | |||
1311 | uart->port.membase = ioremap(res->start, | ||
1312 | res->end - res->start); | ||
1313 | if (!uart->port.membase) { | ||
1314 | dev_err(&pdev->dev, "Cannot map uart IO\n"); | ||
1315 | ret = -ENXIO; | ||
1316 | goto out_error_free_peripherals; | ||
1317 | } | ||
1318 | uart->port.mapbase = res->start; | ||
1319 | |||
1320 | uart->port.irq = platform_get_irq(pdev, 0); | ||
1321 | if (uart->port.irq < 0) { | ||
1322 | dev_err(&pdev->dev, "No uart RX/TX IRQ specified\n"); | ||
1323 | ret = -ENOENT; | ||
1324 | goto out_error_unmap; | ||
1325 | } | ||
1386 | 1326 | ||
1387 | if (i < dev->num_resources) { | 1327 | uart->status_irq = platform_get_irq(pdev, 1); |
1388 | for (i = 0; i < nr_active_ports; i++, res++) { | 1328 | if (uart->status_irq < 0) { |
1389 | if (bfin_serial_ports[i].port.mapbase != res->start) | 1329 | dev_err(&pdev->dev, "No uart status IRQ specified\n"); |
1390 | continue; | 1330 | ret = -ENOENT; |
1391 | bfin_serial_ports[i].port.dev = &dev->dev; | 1331 | goto out_error_unmap; |
1392 | uart_add_one_port(&bfin_serial_reg, &bfin_serial_ports[i].port); | ||
1393 | } | 1332 | } |
1333 | |||
1334 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
1335 | uart->tx_done = 1; | ||
1336 | uart->tx_count = 0; | ||
1337 | |||
1338 | res = platform_get_resource(pdev, IORESOURCE_DMA, 0); | ||
1339 | if (res == NULL) { | ||
1340 | dev_err(&pdev->dev, "No uart TX DMA channel specified\n"); | ||
1341 | ret = -ENOENT; | ||
1342 | goto out_error_unmap; | ||
1343 | } | ||
1344 | uart->tx_dma_channel = res->start; | ||
1345 | |||
1346 | res = platform_get_resource(pdev, IORESOURCE_DMA, 1); | ||
1347 | if (res == NULL) { | ||
1348 | dev_err(&pdev->dev, "No uart RX DMA channel specified\n"); | ||
1349 | ret = -ENOENT; | ||
1350 | goto out_error_unmap; | ||
1351 | } | ||
1352 | uart->rx_dma_channel = res->start; | ||
1353 | |||
1354 | init_timer(&(uart->rx_dma_timer)); | ||
1355 | #endif | ||
1356 | |||
1357 | #if defined(CONFIG_SERIAL_BFIN_CTSRTS) || \ | ||
1358 | defined(CONFIG_SERIAL_BFIN_HARD_CTSRTS) | ||
1359 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | ||
1360 | if (res == NULL) | ||
1361 | uart->cts_pin = -1; | ||
1362 | else | ||
1363 | uart->cts_pin = res->start; | ||
1364 | |||
1365 | res = platform_get_resource(pdev, IORESOURCE_IO, 1); | ||
1366 | if (res == NULL) | ||
1367 | uart->rts_pin = -1; | ||
1368 | else | ||
1369 | uart->rts_pin = res->start; | ||
1370 | # if defined(CONFIG_SERIAL_BFIN_CTSRTS) | ||
1371 | if (uart->rts_pin >= 0) | ||
1372 | gpio_request(uart->rts_pin, DRIVER_NAME); | ||
1373 | # endif | ||
1374 | #endif | ||
1394 | } | 1375 | } |
1395 | 1376 | ||
1396 | return 0; | 1377 | #ifdef CONFIG_SERIAL_BFIN_CONSOLE |
1378 | if (!is_early_platform_device(pdev)) { | ||
1379 | #endif | ||
1380 | uart = bfin_serial_ports[pdev->id]; | ||
1381 | uart->port.dev = &pdev->dev; | ||
1382 | dev_set_drvdata(&pdev->dev, uart); | ||
1383 | ret = uart_add_one_port(&bfin_serial_reg, &uart->port); | ||
1384 | #ifdef CONFIG_SERIAL_BFIN_CONSOLE | ||
1385 | } | ||
1386 | #endif | ||
1387 | |||
1388 | if (!ret) | ||
1389 | return 0; | ||
1390 | |||
1391 | if (uart) { | ||
1392 | out_error_unmap: | ||
1393 | iounmap(uart->port.membase); | ||
1394 | out_error_free_peripherals: | ||
1395 | peripheral_free_list( | ||
1396 | (unsigned short *)pdev->dev.platform_data); | ||
1397 | out_error_free_mem: | ||
1398 | kfree(uart); | ||
1399 | bfin_serial_ports[pdev->id] = NULL; | ||
1400 | } | ||
1401 | |||
1402 | return ret; | ||
1397 | } | 1403 | } |
1398 | 1404 | ||
1399 | static int bfin_serial_remove(struct platform_device *dev) | 1405 | static int __devexit bfin_serial_remove(struct platform_device *pdev) |
1400 | { | 1406 | { |
1401 | int i; | 1407 | struct bfin_serial_port *uart = platform_get_drvdata(pdev); |
1402 | 1408 | ||
1403 | for (i = 0; i < nr_active_ports; i++) { | 1409 | dev_set_drvdata(&pdev->dev, NULL); |
1404 | if (bfin_serial_ports[i].port.dev != &dev->dev) | 1410 | |
1405 | continue; | 1411 | if (uart) { |
1406 | uart_remove_one_port(&bfin_serial_reg, &bfin_serial_ports[i].port); | 1412 | uart_remove_one_port(&bfin_serial_reg, &uart->port); |
1407 | bfin_serial_ports[i].port.dev = NULL; | 1413 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS |
1408 | #if defined(CONFIG_SERIAL_BFIN_CTSRTS) || \ | 1414 | if (uart->rts_pin >= 0) |
1409 | defined(CONFIG_SERIAL_BFIN_HARD_CTSRTS) | 1415 | gpio_free(uart->rts_pin); |
1410 | gpio_free(bfin_serial_ports[i].cts_pin); | ||
1411 | gpio_free(bfin_serial_ports[i].rts_pin); | ||
1412 | #endif | 1416 | #endif |
1417 | iounmap(uart->port.membase); | ||
1418 | peripheral_free_list( | ||
1419 | (unsigned short *)pdev->dev.platform_data); | ||
1420 | kfree(uart); | ||
1421 | bfin_serial_ports[pdev->id] = NULL; | ||
1413 | } | 1422 | } |
1414 | 1423 | ||
1415 | return 0; | 1424 | return 0; |
@@ -1417,31 +1426,160 @@ static int bfin_serial_remove(struct platform_device *dev) | |||
1417 | 1426 | ||
1418 | static struct platform_driver bfin_serial_driver = { | 1427 | static struct platform_driver bfin_serial_driver = { |
1419 | .probe = bfin_serial_probe, | 1428 | .probe = bfin_serial_probe, |
1420 | .remove = bfin_serial_remove, | 1429 | .remove = __devexit_p(bfin_serial_remove), |
1421 | .suspend = bfin_serial_suspend, | 1430 | .suspend = bfin_serial_suspend, |
1422 | .resume = bfin_serial_resume, | 1431 | .resume = bfin_serial_resume, |
1423 | .driver = { | 1432 | .driver = { |
1424 | .name = "bfin-uart", | 1433 | .name = DRIVER_NAME, |
1425 | .owner = THIS_MODULE, | 1434 | .owner = THIS_MODULE, |
1426 | }, | 1435 | }, |
1427 | }; | 1436 | }; |
1428 | 1437 | ||
1429 | static int __init bfin_serial_init(void) | 1438 | #if defined(CONFIG_SERIAL_BFIN_CONSOLE) |
1439 | static __initdata struct early_platform_driver early_bfin_serial_driver = { | ||
1440 | .class_str = CLASS_BFIN_CONSOLE, | ||
1441 | .pdrv = &bfin_serial_driver, | ||
1442 | .requested_id = EARLY_PLATFORM_ID_UNSET, | ||
1443 | }; | ||
1444 | |||
1445 | static int __init bfin_serial_rs_console_init(void) | ||
1446 | { | ||
1447 | early_platform_driver_register(&early_bfin_serial_driver, DRIVER_NAME); | ||
1448 | |||
1449 | early_platform_driver_probe(CLASS_BFIN_CONSOLE, BFIN_UART_NR_PORTS, 0); | ||
1450 | |||
1451 | register_console(&bfin_serial_console); | ||
1452 | |||
1453 | return 0; | ||
1454 | } | ||
1455 | console_initcall(bfin_serial_rs_console_init); | ||
1456 | #endif | ||
1457 | |||
1458 | #ifdef CONFIG_EARLY_PRINTK | ||
1459 | /* | ||
1460 | * Memory can't be allocated dynamically during earlyprink init stage. | ||
1461 | * So, do individual probe for earlyprink with a static uart port variable. | ||
1462 | */ | ||
1463 | static int bfin_earlyprintk_probe(struct platform_device *pdev) | ||
1430 | { | 1464 | { |
1465 | struct resource *res; | ||
1431 | int ret; | 1466 | int ret; |
1432 | 1467 | ||
1433 | pr_info("Serial: Blackfin serial driver\n"); | 1468 | if (pdev->id < 0 || pdev->id >= BFIN_UART_NR_PORTS) { |
1469 | dev_err(&pdev->dev, "Wrong earlyprintk platform device id.\n"); | ||
1470 | return -ENOENT; | ||
1471 | } | ||
1472 | |||
1473 | ret = peripheral_request_list( | ||
1474 | (unsigned short *)pdev->dev.platform_data, DRIVER_NAME); | ||
1475 | if (ret) { | ||
1476 | dev_err(&pdev->dev, | ||
1477 | "fail to request bfin serial peripherals\n"); | ||
1478 | return ret; | ||
1479 | } | ||
1434 | 1480 | ||
1435 | bfin_serial_init_ports(); | 1481 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1482 | if (res == NULL) { | ||
1483 | dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n"); | ||
1484 | ret = -ENOENT; | ||
1485 | goto out_error_free_peripherals; | ||
1486 | } | ||
1487 | |||
1488 | bfin_earlyprintk_port.port.membase = ioremap(res->start, | ||
1489 | res->end - res->start); | ||
1490 | if (!bfin_earlyprintk_port.port.membase) { | ||
1491 | dev_err(&pdev->dev, "Cannot map uart IO\n"); | ||
1492 | ret = -ENXIO; | ||
1493 | goto out_error_free_peripherals; | ||
1494 | } | ||
1495 | bfin_earlyprintk_port.port.mapbase = res->start; | ||
1496 | bfin_earlyprintk_port.port.line = pdev->id; | ||
1497 | bfin_earlyprintk_port.port.uartclk = get_sclk(); | ||
1498 | bfin_earlyprintk_port.port.fifosize = BFIN_UART_TX_FIFO_SIZE; | ||
1499 | spin_lock_init(&bfin_earlyprintk_port.port.lock); | ||
1500 | |||
1501 | return 0; | ||
1502 | |||
1503 | out_error_free_peripherals: | ||
1504 | peripheral_free_list( | ||
1505 | (unsigned short *)pdev->dev.platform_data); | ||
1506 | |||
1507 | return ret; | ||
1508 | } | ||
1509 | |||
1510 | static struct platform_driver bfin_earlyprintk_driver = { | ||
1511 | .probe = bfin_earlyprintk_probe, | ||
1512 | .driver = { | ||
1513 | .name = DRIVER_NAME, | ||
1514 | .owner = THIS_MODULE, | ||
1515 | }, | ||
1516 | }; | ||
1517 | |||
1518 | static __initdata struct early_platform_driver early_bfin_earlyprintk_driver = { | ||
1519 | .class_str = CLASS_BFIN_EARLYPRINTK, | ||
1520 | .pdrv = &bfin_earlyprintk_driver, | ||
1521 | .requested_id = EARLY_PLATFORM_ID_UNSET, | ||
1522 | }; | ||
1523 | |||
1524 | struct console __init *bfin_earlyserial_init(unsigned int port, | ||
1525 | unsigned int cflag) | ||
1526 | { | ||
1527 | struct ktermios t; | ||
1528 | char port_name[20]; | ||
1529 | |||
1530 | if (port < 0 || port >= BFIN_UART_NR_PORTS) | ||
1531 | return NULL; | ||
1532 | |||
1533 | /* | ||
1534 | * Only probe resource of the given port in earlyprintk boot arg. | ||
1535 | * The expected port id should be indicated in port name string. | ||
1536 | */ | ||
1537 | snprintf(port_name, 20, DRIVER_NAME ".%d", port); | ||
1538 | early_platform_driver_register(&early_bfin_earlyprintk_driver, | ||
1539 | port_name); | ||
1540 | early_platform_driver_probe(CLASS_BFIN_EARLYPRINTK, 1, 0); | ||
1541 | |||
1542 | if (!bfin_earlyprintk_port.port.membase) | ||
1543 | return NULL; | ||
1544 | |||
1545 | #ifdef CONFIG_SERIAL_BFIN_CONSOLE | ||
1546 | /* | ||
1547 | * If we are using early serial, don't let the normal console rewind | ||
1548 | * log buffer, since that causes things to be printed multiple times | ||
1549 | */ | ||
1550 | bfin_serial_console.flags &= ~CON_PRINTBUFFER; | ||
1551 | #endif | ||
1552 | |||
1553 | bfin_early_serial_console.index = port; | ||
1554 | t.c_cflag = cflag; | ||
1555 | t.c_iflag = 0; | ||
1556 | t.c_oflag = 0; | ||
1557 | t.c_lflag = ICANON; | ||
1558 | t.c_line = port; | ||
1559 | bfin_serial_set_termios(&bfin_earlyprintk_port.port, &t, &t); | ||
1560 | |||
1561 | return &bfin_early_serial_console; | ||
1562 | } | ||
1563 | #endif /* CONFIG_EARLY_PRINTK */ | ||
1564 | |||
1565 | static int __init bfin_serial_init(void) | ||
1566 | { | ||
1567 | int ret; | ||
1568 | |||
1569 | pr_info("Blackfin serial driver\n"); | ||
1436 | 1570 | ||
1437 | ret = uart_register_driver(&bfin_serial_reg); | 1571 | ret = uart_register_driver(&bfin_serial_reg); |
1438 | if (ret == 0) { | 1572 | if (ret) { |
1439 | ret = platform_driver_register(&bfin_serial_driver); | 1573 | pr_err("failed to register %s:%d\n", |
1440 | if (ret) { | 1574 | bfin_serial_reg.driver_name, ret); |
1441 | pr_debug("uart register failed\n"); | 1575 | } |
1442 | uart_unregister_driver(&bfin_serial_reg); | 1576 | |
1443 | } | 1577 | ret = platform_driver_register(&bfin_serial_driver); |
1578 | if (ret) { | ||
1579 | pr_err("fail to register bfin uart\n"); | ||
1580 | uart_unregister_driver(&bfin_serial_reg); | ||
1444 | } | 1581 | } |
1582 | |||
1445 | return ret; | 1583 | return ret; |
1446 | } | 1584 | } |
1447 | 1585 | ||
@@ -1455,7 +1593,7 @@ static void __exit bfin_serial_exit(void) | |||
1455 | module_init(bfin_serial_init); | 1593 | module_init(bfin_serial_init); |
1456 | module_exit(bfin_serial_exit); | 1594 | module_exit(bfin_serial_exit); |
1457 | 1595 | ||
1458 | MODULE_AUTHOR("Aubrey.Li <aubrey.li@analog.com>"); | 1596 | MODULE_AUTHOR("Sonic Zhang, Aubrey Li"); |
1459 | MODULE_DESCRIPTION("Blackfin generic serial port driver"); | 1597 | MODULE_DESCRIPTION("Blackfin generic serial port driver"); |
1460 | MODULE_LICENSE("GPL"); | 1598 | MODULE_LICENSE("GPL"); |
1461 | MODULE_ALIAS_CHARDEV_MAJOR(BFIN_SERIAL_MAJOR); | 1599 | MODULE_ALIAS_CHARDEV_MAJOR(BFIN_SERIAL_MAJOR); |
diff --git a/drivers/serial/bfin_sport_uart.c b/drivers/serial/bfin_sport_uart.c index 34b4ae0fe760..e95c524d9d18 100644 --- a/drivers/serial/bfin_sport_uart.c +++ b/drivers/serial/bfin_sport_uart.c | |||
@@ -1,134 +1,101 @@ | |||
1 | /* | 1 | /* |
2 | * File: linux/drivers/serial/bfin_sport_uart.c | 2 | * Blackfin On-Chip Sport Emulated UART Driver |
3 | * | 3 | * |
4 | * Based on: drivers/serial/bfin_5xx.c by Aubrey Li. | 4 | * Copyright 2006-2009 Analog Devices Inc. |
5 | * Author: Roy Huang <roy.huang@analog.com> | ||
6 | * | 5 | * |
7 | * Created: Nov 22, 2006 | 6 | * Enter bugs at http://blackfin.uclinux.org/ |
8 | * Copyright: (c) 2006-2007 Analog Devices Inc. | ||
9 | * Description: this driver enable SPORTs on Blackfin emulate UART. | ||
10 | * | 7 | * |
11 | * This program is free software; you can redistribute it and/or modify | 8 | * Licensed under the GPL-2 or later. |
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, see the file COPYING, or write | ||
23 | * to the Free Software Foundation, Inc., | ||
24 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
25 | */ | 9 | */ |
26 | 10 | ||
27 | /* | 11 | /* |
28 | * This driver and the hardware supported are in term of EE-191 of ADI. | 12 | * This driver and the hardware supported are in term of EE-191 of ADI. |
29 | * http://www.analog.com/UploadedFiles/Application_Notes/399447663EE191.pdf | 13 | * http://www.analog.com/static/imported-files/application_notes/EE191.pdf |
30 | * This application note describe how to implement a UART on a Sharc DSP, | 14 | * This application note describe how to implement a UART on a Sharc DSP, |
31 | * but this driver is implemented on Blackfin Processor. | 15 | * but this driver is implemented on Blackfin Processor. |
16 | * Transmit Frame Sync is not used by this driver to transfer data out. | ||
32 | */ | 17 | */ |
33 | 18 | ||
34 | /* After reset, there is a prelude of low level pulse when transmit data first | 19 | /* #define DEBUG */ |
35 | * time. No addtional pulse in following transmit. | ||
36 | * According to document: | ||
37 | * The SPORTs are ready to start transmitting or receiving data no later than | ||
38 | * three serial clock cycles after they are enabled in the SPORTx_TCR1 or | ||
39 | * SPORTx_RCR1 register. No serial clock cycles are lost from this point on. | ||
40 | * The first internal frame sync will occur one frame sync delay after the | ||
41 | * SPORTs are ready. External frame syncs can occur as soon as the SPORT is | ||
42 | * ready. | ||
43 | */ | ||
44 | 20 | ||
45 | /* Thanks to Axel Alatalo <axel@rubico.se> for fixing sport rx bug. Sometimes | 21 | #define DRV_NAME "bfin-sport-uart" |
46 | * sport receives data incorrectly. The following is Axel's words. | 22 | #define DEVICE_NAME "ttySS" |
47 | * As EE-191, sport rx samples 3 times of the UART baudrate and takes the | 23 | #define pr_fmt(fmt) DRV_NAME ": " fmt |
48 | * middle smaple of every 3 samples as the data bit. For a 8-N-1 UART setting, | ||
49 | * 30 samples will be required for a byte. If transmitter sends a 1/3 bit short | ||
50 | * byte due to buadrate drift, then the 30th sample of a byte, this sample is | ||
51 | * also the third sample of the stop bit, will happens on the immediately | ||
52 | * following start bit which will be thrown away and missed. Thus since parts | ||
53 | * of the startbit will be missed and the receiver will begin to drift, the | ||
54 | * effect accumulates over time until synchronization is lost. | ||
55 | * If only require 2 samples of the stopbit (by sampling in total 29 samples), | ||
56 | * then a to short byte as in the case above will be tolerated. Then the 1/3 | ||
57 | * early startbit will trigger a framesync since the last read is complete | ||
58 | * after only 2/3 stopbit and framesync is active during the last 1/3 looking | ||
59 | * for a possible early startbit. */ | ||
60 | |||
61 | //#define DEBUG | ||
62 | 24 | ||
63 | #include <linux/module.h> | 25 | #include <linux/module.h> |
64 | #include <linux/ioport.h> | 26 | #include <linux/ioport.h> |
27 | #include <linux/io.h> | ||
65 | #include <linux/init.h> | 28 | #include <linux/init.h> |
66 | #include <linux/console.h> | 29 | #include <linux/console.h> |
67 | #include <linux/sysrq.h> | 30 | #include <linux/sysrq.h> |
31 | #include <linux/slab.h> | ||
68 | #include <linux/platform_device.h> | 32 | #include <linux/platform_device.h> |
69 | #include <linux/tty.h> | 33 | #include <linux/tty.h> |
70 | #include <linux/tty_flip.h> | 34 | #include <linux/tty_flip.h> |
71 | #include <linux/serial_core.h> | 35 | #include <linux/serial_core.h> |
72 | 36 | ||
37 | #include <asm/bfin_sport.h> | ||
73 | #include <asm/delay.h> | 38 | #include <asm/delay.h> |
74 | #include <asm/portmux.h> | 39 | #include <asm/portmux.h> |
75 | 40 | ||
76 | #include "bfin_sport_uart.h" | 41 | #include "bfin_sport_uart.h" |
77 | 42 | ||
78 | unsigned short bfin_uart_pin_req_sport0[] = | ||
79 | {P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, \ | ||
80 | P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0}; | ||
81 | |||
82 | unsigned short bfin_uart_pin_req_sport1[] = | ||
83 | {P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, \ | ||
84 | P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0}; | ||
85 | |||
86 | #define DRV_NAME "bfin-sport-uart" | ||
87 | |||
88 | struct sport_uart_port { | 43 | struct sport_uart_port { |
89 | struct uart_port port; | 44 | struct uart_port port; |
90 | char *name; | ||
91 | |||
92 | int tx_irq; | ||
93 | int rx_irq; | ||
94 | int err_irq; | 45 | int err_irq; |
46 | unsigned short csize; | ||
47 | unsigned short rxmask; | ||
48 | unsigned short txmask1; | ||
49 | unsigned short txmask2; | ||
50 | unsigned char stopb; | ||
51 | /* unsigned char parib; */ | ||
52 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS | ||
53 | int cts_pin; | ||
54 | int rts_pin; | ||
55 | #endif | ||
95 | }; | 56 | }; |
96 | 57 | ||
97 | static void sport_uart_tx_chars(struct sport_uart_port *up); | 58 | static int sport_uart_tx_chars(struct sport_uart_port *up); |
98 | static void sport_stop_tx(struct uart_port *port); | 59 | static void sport_stop_tx(struct uart_port *port); |
99 | 60 | ||
100 | static inline void tx_one_byte(struct sport_uart_port *up, unsigned int value) | 61 | static inline void tx_one_byte(struct sport_uart_port *up, unsigned int value) |
101 | { | 62 | { |
102 | pr_debug("%s value:%x\n", __func__, value); | 63 | pr_debug("%s value:%x, mask1=0x%x, mask2=0x%x\n", __func__, value, |
103 | /* Place a Start and Stop bit */ | 64 | up->txmask1, up->txmask2); |
65 | |||
66 | /* Place Start and Stop bits */ | ||
104 | __asm__ __volatile__ ( | 67 | __asm__ __volatile__ ( |
105 | "R2 = b#01111111100;" | 68 | "%[val] <<= 1;" |
106 | "R3 = b#10000000001;" | 69 | "%[val] = %[val] & %[mask1];" |
107 | "%0 <<= 2;" | 70 | "%[val] = %[val] | %[mask2];" |
108 | "%0 = %0 & R2;" | 71 | : [val]"+d"(value) |
109 | "%0 = %0 | R3;" | 72 | : [mask1]"d"(up->txmask1), [mask2]"d"(up->txmask2) |
110 | : "=d"(value) | 73 | : "ASTAT" |
111 | : "d"(value) | ||
112 | : "ASTAT", "R2", "R3" | ||
113 | ); | 74 | ); |
114 | pr_debug("%s value:%x\n", __func__, value); | 75 | pr_debug("%s value:%x\n", __func__, value); |
115 | 76 | ||
116 | SPORT_PUT_TX(up, value); | 77 | SPORT_PUT_TX(up, value); |
117 | } | 78 | } |
118 | 79 | ||
119 | static inline unsigned int rx_one_byte(struct sport_uart_port *up) | 80 | static inline unsigned char rx_one_byte(struct sport_uart_port *up) |
120 | { | 81 | { |
121 | unsigned int value, extract; | 82 | unsigned int value; |
83 | unsigned char extract; | ||
122 | u32 tmp_mask1, tmp_mask2, tmp_shift, tmp; | 84 | u32 tmp_mask1, tmp_mask2, tmp_shift, tmp; |
123 | 85 | ||
124 | value = SPORT_GET_RX32(up); | 86 | if ((up->csize + up->stopb) > 7) |
125 | pr_debug("%s value:%x\n", __func__, value); | 87 | value = SPORT_GET_RX32(up); |
88 | else | ||
89 | value = SPORT_GET_RX(up); | ||
126 | 90 | ||
127 | /* Extract 8 bits data */ | 91 | pr_debug("%s value:%x, cs=%d, mask=0x%x\n", __func__, value, |
92 | up->csize, up->rxmask); | ||
93 | |||
94 | /* Extract data */ | ||
128 | __asm__ __volatile__ ( | 95 | __asm__ __volatile__ ( |
129 | "%[extr] = 0;" | 96 | "%[extr] = 0;" |
130 | "%[mask1] = 0x1801(Z);" | 97 | "%[mask1] = %[rxmask];" |
131 | "%[mask2] = 0x0300(Z);" | 98 | "%[mask2] = 0x0200(Z);" |
132 | "%[shift] = 0;" | 99 | "%[shift] = 0;" |
133 | "LSETUP(.Lloop_s, .Lloop_e) LC0 = %[lc];" | 100 | "LSETUP(.Lloop_s, .Lloop_e) LC0 = %[lc];" |
134 | ".Lloop_s:" | 101 | ".Lloop_s:" |
@@ -138,9 +105,9 @@ static inline unsigned int rx_one_byte(struct sport_uart_port *up) | |||
138 | "%[mask1] = %[mask1] - %[mask2];" | 105 | "%[mask1] = %[mask1] - %[mask2];" |
139 | ".Lloop_e:" | 106 | ".Lloop_e:" |
140 | "%[shift] += 1;" | 107 | "%[shift] += 1;" |
141 | : [val]"=d"(value), [extr]"=d"(extract), [shift]"=d"(tmp_shift), [tmp]"=d"(tmp), | 108 | : [extr]"=&d"(extract), [shift]"=&d"(tmp_shift), [tmp]"=&d"(tmp), |
142 | [mask1]"=d"(tmp_mask1), [mask2]"=d"(tmp_mask2) | 109 | [mask1]"=&d"(tmp_mask1), [mask2]"=&d"(tmp_mask2) |
143 | : "d"(value), [lc]"a"(8) | 110 | : [val]"d"(value), [rxmask]"d"(up->rxmask), [lc]"a"(up->csize) |
144 | : "ASTAT", "LB0", "LC0", "LT0" | 111 | : "ASTAT", "LB0", "LC0", "LT0" |
145 | ); | 112 | ); |
146 | 113 | ||
@@ -148,29 +115,33 @@ static inline unsigned int rx_one_byte(struct sport_uart_port *up) | |||
148 | return extract; | 115 | return extract; |
149 | } | 116 | } |
150 | 117 | ||
151 | static int sport_uart_setup(struct sport_uart_port *up, int sclk, int baud_rate) | 118 | static int sport_uart_setup(struct sport_uart_port *up, int size, int baud_rate) |
152 | { | 119 | { |
153 | int tclkdiv, tfsdiv, rclkdiv; | 120 | int tclkdiv, rclkdiv; |
121 | unsigned int sclk = get_sclk(); | ||
154 | 122 | ||
155 | /* Set TCR1 and TCR2 */ | 123 | /* Set TCR1 and TCR2, TFSR is not enabled for uart */ |
156 | SPORT_PUT_TCR1(up, (LATFS | ITFS | TFSR | TLSBIT | ITCLK)); | 124 | SPORT_PUT_TCR1(up, (LATFS | ITFS | TFSR | TLSBIT | ITCLK)); |
157 | SPORT_PUT_TCR2(up, 10); | 125 | SPORT_PUT_TCR2(up, size + 1); |
158 | pr_debug("%s TCR1:%x, TCR2:%x\n", __func__, SPORT_GET_TCR1(up), SPORT_GET_TCR2(up)); | 126 | pr_debug("%s TCR1:%x, TCR2:%x\n", __func__, SPORT_GET_TCR1(up), SPORT_GET_TCR2(up)); |
159 | 127 | ||
160 | /* Set RCR1 and RCR2 */ | 128 | /* Set RCR1 and RCR2 */ |
161 | SPORT_PUT_RCR1(up, (RCKFE | LARFS | LRFS | RFSR | IRCLK)); | 129 | SPORT_PUT_RCR1(up, (RCKFE | LARFS | LRFS | RFSR | IRCLK)); |
162 | SPORT_PUT_RCR2(up, 28); | 130 | SPORT_PUT_RCR2(up, (size + 1) * 2 - 1); |
163 | pr_debug("%s RCR1:%x, RCR2:%x\n", __func__, SPORT_GET_RCR1(up), SPORT_GET_RCR2(up)); | 131 | pr_debug("%s RCR1:%x, RCR2:%x\n", __func__, SPORT_GET_RCR1(up), SPORT_GET_RCR2(up)); |
164 | 132 | ||
165 | tclkdiv = sclk/(2 * baud_rate) - 1; | 133 | tclkdiv = sclk / (2 * baud_rate) - 1; |
166 | tfsdiv = 12; | 134 | /* The actual uart baud rate of devices vary between +/-2%. The sport |
167 | rclkdiv = sclk/(2 * baud_rate * 3) - 1; | 135 | * RX sample rate should be faster than the double of the worst case, |
136 | * otherwise, wrong data are received. So, set sport RX clock to be | ||
137 | * 3% faster. | ||
138 | */ | ||
139 | rclkdiv = sclk / (2 * baud_rate * 2 * 97 / 100) - 1; | ||
168 | SPORT_PUT_TCLKDIV(up, tclkdiv); | 140 | SPORT_PUT_TCLKDIV(up, tclkdiv); |
169 | SPORT_PUT_TFSDIV(up, tfsdiv); | ||
170 | SPORT_PUT_RCLKDIV(up, rclkdiv); | 141 | SPORT_PUT_RCLKDIV(up, rclkdiv); |
171 | SSYNC(); | 142 | SSYNC(); |
172 | pr_debug("%s sclk:%d, baud_rate:%d, tclkdiv:%d, tfsdiv:%d, rclkdiv:%d\n", | 143 | pr_debug("%s sclk:%d, baud_rate:%d, tclkdiv:%d, rclkdiv:%d\n", |
173 | __func__, sclk, baud_rate, tclkdiv, tfsdiv, rclkdiv); | 144 | __func__, sclk, baud_rate, tclkdiv, rclkdiv); |
174 | 145 | ||
175 | return 0; | 146 | return 0; |
176 | } | 147 | } |
@@ -178,26 +149,32 @@ static int sport_uart_setup(struct sport_uart_port *up, int sclk, int baud_rate) | |||
178 | static irqreturn_t sport_uart_rx_irq(int irq, void *dev_id) | 149 | static irqreturn_t sport_uart_rx_irq(int irq, void *dev_id) |
179 | { | 150 | { |
180 | struct sport_uart_port *up = dev_id; | 151 | struct sport_uart_port *up = dev_id; |
181 | struct tty_struct *tty = up->port.info->port.tty; | 152 | struct tty_struct *tty = up->port.state->port.tty; |
182 | unsigned int ch; | 153 | unsigned int ch; |
183 | 154 | ||
184 | do { | 155 | spin_lock(&up->port.lock); |
156 | |||
157 | while (SPORT_GET_STAT(up) & RXNE) { | ||
185 | ch = rx_one_byte(up); | 158 | ch = rx_one_byte(up); |
186 | up->port.icount.rx++; | 159 | up->port.icount.rx++; |
187 | 160 | ||
188 | if (uart_handle_sysrq_char(&up->port, ch)) | 161 | if (!uart_handle_sysrq_char(&up->port, ch)) |
189 | ; | ||
190 | else | ||
191 | tty_insert_flip_char(tty, ch, TTY_NORMAL); | 162 | tty_insert_flip_char(tty, ch, TTY_NORMAL); |
192 | } while (SPORT_GET_STAT(up) & RXNE); | 163 | } |
193 | tty_flip_buffer_push(tty); | 164 | tty_flip_buffer_push(tty); |
194 | 165 | ||
166 | spin_unlock(&up->port.lock); | ||
167 | |||
195 | return IRQ_HANDLED; | 168 | return IRQ_HANDLED; |
196 | } | 169 | } |
197 | 170 | ||
198 | static irqreturn_t sport_uart_tx_irq(int irq, void *dev_id) | 171 | static irqreturn_t sport_uart_tx_irq(int irq, void *dev_id) |
199 | { | 172 | { |
200 | sport_uart_tx_chars(dev_id); | 173 | struct sport_uart_port *up = dev_id; |
174 | |||
175 | spin_lock(&up->port.lock); | ||
176 | sport_uart_tx_chars(up); | ||
177 | spin_unlock(&up->port.lock); | ||
201 | 178 | ||
202 | return IRQ_HANDLED; | 179 | return IRQ_HANDLED; |
203 | } | 180 | } |
@@ -205,9 +182,11 @@ static irqreturn_t sport_uart_tx_irq(int irq, void *dev_id) | |||
205 | static irqreturn_t sport_uart_err_irq(int irq, void *dev_id) | 182 | static irqreturn_t sport_uart_err_irq(int irq, void *dev_id) |
206 | { | 183 | { |
207 | struct sport_uart_port *up = dev_id; | 184 | struct sport_uart_port *up = dev_id; |
208 | struct tty_struct *tty = up->port.info->port.tty; | 185 | struct tty_struct *tty = up->port.state->port.tty; |
209 | unsigned int stat = SPORT_GET_STAT(up); | 186 | unsigned int stat = SPORT_GET_STAT(up); |
210 | 187 | ||
188 | spin_lock(&up->port.lock); | ||
189 | |||
211 | /* Overflow in RX FIFO */ | 190 | /* Overflow in RX FIFO */ |
212 | if (stat & ROVF) { | 191 | if (stat & ROVF) { |
213 | up->port.icount.overrun++; | 192 | up->port.icount.overrun++; |
@@ -216,96 +195,153 @@ static irqreturn_t sport_uart_err_irq(int irq, void *dev_id) | |||
216 | } | 195 | } |
217 | /* These should not happen */ | 196 | /* These should not happen */ |
218 | if (stat & (TOVF | TUVF | RUVF)) { | 197 | if (stat & (TOVF | TUVF | RUVF)) { |
219 | printk(KERN_ERR "SPORT Error:%s %s %s\n", | 198 | pr_err("SPORT Error:%s %s %s\n", |
220 | (stat & TOVF)?"TX overflow":"", | 199 | (stat & TOVF) ? "TX overflow" : "", |
221 | (stat & TUVF)?"TX underflow":"", | 200 | (stat & TUVF) ? "TX underflow" : "", |
222 | (stat & RUVF)?"RX underflow":""); | 201 | (stat & RUVF) ? "RX underflow" : ""); |
223 | SPORT_PUT_TCR1(up, SPORT_GET_TCR1(up) & ~TSPEN); | 202 | SPORT_PUT_TCR1(up, SPORT_GET_TCR1(up) & ~TSPEN); |
224 | SPORT_PUT_RCR1(up, SPORT_GET_RCR1(up) & ~RSPEN); | 203 | SPORT_PUT_RCR1(up, SPORT_GET_RCR1(up) & ~RSPEN); |
225 | } | 204 | } |
226 | SSYNC(); | 205 | SSYNC(); |
227 | 206 | ||
207 | spin_unlock(&up->port.lock); | ||
228 | return IRQ_HANDLED; | 208 | return IRQ_HANDLED; |
229 | } | 209 | } |
230 | 210 | ||
211 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS | ||
212 | static unsigned int sport_get_mctrl(struct uart_port *port) | ||
213 | { | ||
214 | struct sport_uart_port *up = (struct sport_uart_port *)port; | ||
215 | if (up->cts_pin < 0) | ||
216 | return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; | ||
217 | |||
218 | /* CTS PIN is negative assertive. */ | ||
219 | if (SPORT_UART_GET_CTS(up)) | ||
220 | return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; | ||
221 | else | ||
222 | return TIOCM_DSR | TIOCM_CAR; | ||
223 | } | ||
224 | |||
225 | static void sport_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
226 | { | ||
227 | struct sport_uart_port *up = (struct sport_uart_port *)port; | ||
228 | if (up->rts_pin < 0) | ||
229 | return; | ||
230 | |||
231 | /* RTS PIN is negative assertive. */ | ||
232 | if (mctrl & TIOCM_RTS) | ||
233 | SPORT_UART_ENABLE_RTS(up); | ||
234 | else | ||
235 | SPORT_UART_DISABLE_RTS(up); | ||
236 | } | ||
237 | |||
238 | /* | ||
239 | * Handle any change of modem status signal. | ||
240 | */ | ||
241 | static irqreturn_t sport_mctrl_cts_int(int irq, void *dev_id) | ||
242 | { | ||
243 | struct sport_uart_port *up = (struct sport_uart_port *)dev_id; | ||
244 | unsigned int status; | ||
245 | |||
246 | status = sport_get_mctrl(&up->port); | ||
247 | uart_handle_cts_change(&up->port, status & TIOCM_CTS); | ||
248 | |||
249 | return IRQ_HANDLED; | ||
250 | } | ||
251 | #else | ||
252 | static unsigned int sport_get_mctrl(struct uart_port *port) | ||
253 | { | ||
254 | pr_debug("%s enter\n", __func__); | ||
255 | return TIOCM_CTS | TIOCM_CD | TIOCM_DSR; | ||
256 | } | ||
257 | |||
258 | static void sport_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
259 | { | ||
260 | pr_debug("%s enter\n", __func__); | ||
261 | } | ||
262 | #endif | ||
263 | |||
231 | /* Reqeust IRQ, Setup clock */ | 264 | /* Reqeust IRQ, Setup clock */ |
232 | static int sport_startup(struct uart_port *port) | 265 | static int sport_startup(struct uart_port *port) |
233 | { | 266 | { |
234 | struct sport_uart_port *up = (struct sport_uart_port *)port; | 267 | struct sport_uart_port *up = (struct sport_uart_port *)port; |
235 | char buffer[20]; | 268 | int ret; |
236 | int retval; | ||
237 | 269 | ||
238 | pr_debug("%s enter\n", __func__); | 270 | pr_debug("%s enter\n", __func__); |
239 | memset(buffer, 20, '\0'); | 271 | ret = request_irq(up->port.irq, sport_uart_rx_irq, 0, |
240 | snprintf(buffer, 20, "%s rx", up->name); | 272 | "SPORT_UART_RX", up); |
241 | retval = request_irq(up->rx_irq, sport_uart_rx_irq, IRQF_SAMPLE_RANDOM, buffer, up); | 273 | if (ret) { |
242 | if (retval) { | 274 | dev_err(port->dev, "unable to request SPORT RX interrupt\n"); |
243 | printk(KERN_ERR "Unable to request interrupt %s\n", buffer); | 275 | return ret; |
244 | return retval; | ||
245 | } | 276 | } |
246 | 277 | ||
247 | snprintf(buffer, 20, "%s tx", up->name); | 278 | ret = request_irq(up->port.irq+1, sport_uart_tx_irq, 0, |
248 | retval = request_irq(up->tx_irq, sport_uart_tx_irq, IRQF_SAMPLE_RANDOM, buffer, up); | 279 | "SPORT_UART_TX", up); |
249 | if (retval) { | 280 | if (ret) { |
250 | printk(KERN_ERR "Unable to request interrupt %s\n", buffer); | 281 | dev_err(port->dev, "unable to request SPORT TX interrupt\n"); |
251 | goto fail1; | 282 | goto fail1; |
252 | } | 283 | } |
253 | 284 | ||
254 | snprintf(buffer, 20, "%s err", up->name); | 285 | ret = request_irq(up->err_irq, sport_uart_err_irq, 0, |
255 | retval = request_irq(up->err_irq, sport_uart_err_irq, IRQF_SAMPLE_RANDOM, buffer, up); | 286 | "SPORT_UART_STATUS", up); |
256 | if (retval) { | 287 | if (ret) { |
257 | printk(KERN_ERR "Unable to request interrupt %s\n", buffer); | 288 | dev_err(port->dev, "unable to request SPORT status interrupt\n"); |
258 | goto fail2; | 289 | goto fail2; |
259 | } | 290 | } |
260 | 291 | ||
261 | if (port->line) { | 292 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS |
262 | if (peripheral_request_list(bfin_uart_pin_req_sport1, DRV_NAME)) | 293 | if (up->cts_pin >= 0) { |
263 | goto fail3; | 294 | if (request_irq(gpio_to_irq(up->cts_pin), |
264 | } else { | 295 | sport_mctrl_cts_int, |
265 | if (peripheral_request_list(bfin_uart_pin_req_sport0, DRV_NAME)) | 296 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | |
266 | goto fail3; | 297 | IRQF_DISABLED, "BFIN_SPORT_UART_CTS", up)) { |
298 | up->cts_pin = -1; | ||
299 | dev_info(port->dev, "Unable to attach BlackFin UART \ | ||
300 | over SPORT CTS interrupt. So, disable it.\n"); | ||
301 | } | ||
267 | } | 302 | } |
268 | 303 | if (up->rts_pin >= 0) | |
269 | sport_uart_setup(up, get_sclk(), port->uartclk); | 304 | gpio_direction_output(up->rts_pin, 0); |
270 | 305 | #endif | |
271 | /* Enable receive interrupt */ | ||
272 | SPORT_PUT_RCR1(up, (SPORT_GET_RCR1(up) | RSPEN)); | ||
273 | SSYNC(); | ||
274 | 306 | ||
275 | return 0; | 307 | return 0; |
308 | fail2: | ||
309 | free_irq(up->port.irq+1, up); | ||
310 | fail1: | ||
311 | free_irq(up->port.irq, up); | ||
276 | 312 | ||
277 | 313 | return ret; | |
278 | fail3: | ||
279 | printk(KERN_ERR DRV_NAME | ||
280 | ": Requesting Peripherals failed\n"); | ||
281 | |||
282 | free_irq(up->err_irq, up); | ||
283 | fail2: | ||
284 | free_irq(up->tx_irq, up); | ||
285 | fail1: | ||
286 | free_irq(up->rx_irq, up); | ||
287 | |||
288 | return retval; | ||
289 | |||
290 | } | 314 | } |
291 | 315 | ||
292 | static void sport_uart_tx_chars(struct sport_uart_port *up) | 316 | /* |
317 | * sport_uart_tx_chars | ||
318 | * | ||
319 | * ret 1 means need to enable sport. | ||
320 | * ret 0 means do nothing. | ||
321 | */ | ||
322 | static int sport_uart_tx_chars(struct sport_uart_port *up) | ||
293 | { | 323 | { |
294 | struct circ_buf *xmit = &up->port.info->xmit; | 324 | struct circ_buf *xmit = &up->port.state->xmit; |
295 | 325 | ||
296 | if (SPORT_GET_STAT(up) & TXF) | 326 | if (SPORT_GET_STAT(up) & TXF) |
297 | return; | 327 | return 0; |
298 | 328 | ||
299 | if (up->port.x_char) { | 329 | if (up->port.x_char) { |
300 | tx_one_byte(up, up->port.x_char); | 330 | tx_one_byte(up, up->port.x_char); |
301 | up->port.icount.tx++; | 331 | up->port.icount.tx++; |
302 | up->port.x_char = 0; | 332 | up->port.x_char = 0; |
303 | return; | 333 | return 1; |
304 | } | 334 | } |
305 | 335 | ||
306 | if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { | 336 | if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { |
307 | sport_stop_tx(&up->port); | 337 | /* The waiting loop to stop SPORT TX from TX interrupt is |
308 | return; | 338 | * too long. This may block SPORT RX interrupts and cause |
339 | * RX FIFO overflow. So, do stop sport TX only after the last | ||
340 | * char in TX FIFO is moved into the shift register. | ||
341 | */ | ||
342 | if (SPORT_GET_STAT(up) & TXHRE) | ||
343 | sport_stop_tx(&up->port); | ||
344 | return 0; | ||
309 | } | 345 | } |
310 | 346 | ||
311 | while(!(SPORT_GET_STAT(up) & TXF) && !uart_circ_empty(xmit)) { | 347 | while(!(SPORT_GET_STAT(up) & TXF) && !uart_circ_empty(xmit)) { |
@@ -316,6 +352,8 @@ static void sport_uart_tx_chars(struct sport_uart_port *up) | |||
316 | 352 | ||
317 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 353 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
318 | uart_write_wakeup(&up->port); | 354 | uart_write_wakeup(&up->port); |
355 | |||
356 | return 1; | ||
319 | } | 357 | } |
320 | 358 | ||
321 | static unsigned int sport_tx_empty(struct uart_port *port) | 359 | static unsigned int sport_tx_empty(struct uart_port *port) |
@@ -331,34 +369,23 @@ static unsigned int sport_tx_empty(struct uart_port *port) | |||
331 | return 0; | 369 | return 0; |
332 | } | 370 | } |
333 | 371 | ||
334 | static unsigned int sport_get_mctrl(struct uart_port *port) | ||
335 | { | ||
336 | pr_debug("%s enter\n", __func__); | ||
337 | return (TIOCM_CTS | TIOCM_CD | TIOCM_DSR); | ||
338 | } | ||
339 | |||
340 | static void sport_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
341 | { | ||
342 | pr_debug("%s enter\n", __func__); | ||
343 | } | ||
344 | |||
345 | static void sport_stop_tx(struct uart_port *port) | 372 | static void sport_stop_tx(struct uart_port *port) |
346 | { | 373 | { |
347 | struct sport_uart_port *up = (struct sport_uart_port *)port; | 374 | struct sport_uart_port *up = (struct sport_uart_port *)port; |
348 | unsigned int stat; | ||
349 | 375 | ||
350 | pr_debug("%s enter\n", __func__); | 376 | pr_debug("%s enter\n", __func__); |
351 | 377 | ||
352 | stat = SPORT_GET_STAT(up); | 378 | if (!(SPORT_GET_TCR1(up) & TSPEN)) |
353 | while(!(stat & TXHRE)) { | 379 | return; |
354 | udelay(1); | 380 | |
355 | stat = SPORT_GET_STAT(up); | ||
356 | } | ||
357 | /* Although the hold register is empty, last byte is still in shift | 381 | /* Although the hold register is empty, last byte is still in shift |
358 | * register and not sent out yet. If baud rate is lower than default, | 382 | * register and not sent out yet. So, put a dummy data into TX FIFO. |
359 | * delay should be longer. For example, if the baud rate is 9600, | 383 | * Then, sport tx stops when last byte is shift out and the dummy |
360 | * the delay must be at least 2ms by experience */ | 384 | * data is moved into the shift register. |
361 | udelay(500); | 385 | */ |
386 | SPORT_PUT_TX(up, 0xffff); | ||
387 | while (!(SPORT_GET_STAT(up) & TXHRE)) | ||
388 | cpu_relax(); | ||
362 | 389 | ||
363 | SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) & ~TSPEN)); | 390 | SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) & ~TSPEN)); |
364 | SSYNC(); | 391 | SSYNC(); |
@@ -371,12 +398,14 @@ static void sport_start_tx(struct uart_port *port) | |||
371 | struct sport_uart_port *up = (struct sport_uart_port *)port; | 398 | struct sport_uart_port *up = (struct sport_uart_port *)port; |
372 | 399 | ||
373 | pr_debug("%s enter\n", __func__); | 400 | pr_debug("%s enter\n", __func__); |
401 | |||
374 | /* Write data into SPORT FIFO before enable SPROT to transmit */ | 402 | /* Write data into SPORT FIFO before enable SPROT to transmit */ |
375 | sport_uart_tx_chars(up); | 403 | if (sport_uart_tx_chars(up)) { |
404 | /* Enable transmit, then an interrupt will generated */ | ||
405 | SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) | TSPEN)); | ||
406 | SSYNC(); | ||
407 | } | ||
376 | 408 | ||
377 | /* Enable transmit, then an interrupt will generated */ | ||
378 | SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) | TSPEN)); | ||
379 | SSYNC(); | ||
380 | pr_debug("%s exit\n", __func__); | 409 | pr_debug("%s exit\n", __func__); |
381 | } | 410 | } |
382 | 411 | ||
@@ -404,29 +433,20 @@ static void sport_shutdown(struct uart_port *port) | |||
404 | { | 433 | { |
405 | struct sport_uart_port *up = (struct sport_uart_port *)port; | 434 | struct sport_uart_port *up = (struct sport_uart_port *)port; |
406 | 435 | ||
407 | pr_debug("%s enter\n", __func__); | 436 | dev_dbg(port->dev, "%s enter\n", __func__); |
408 | 437 | ||
409 | /* Disable sport */ | 438 | /* Disable sport */ |
410 | SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) & ~TSPEN)); | 439 | SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) & ~TSPEN)); |
411 | SPORT_PUT_RCR1(up, (SPORT_GET_RCR1(up) & ~RSPEN)); | 440 | SPORT_PUT_RCR1(up, (SPORT_GET_RCR1(up) & ~RSPEN)); |
412 | SSYNC(); | 441 | SSYNC(); |
413 | 442 | ||
414 | if (port->line) { | 443 | free_irq(up->port.irq, up); |
415 | peripheral_free_list(bfin_uart_pin_req_sport1); | 444 | free_irq(up->port.irq+1, up); |
416 | } else { | ||
417 | peripheral_free_list(bfin_uart_pin_req_sport0); | ||
418 | } | ||
419 | |||
420 | free_irq(up->rx_irq, up); | ||
421 | free_irq(up->tx_irq, up); | ||
422 | free_irq(up->err_irq, up); | 445 | free_irq(up->err_irq, up); |
423 | } | 446 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS |
424 | 447 | if (up->cts_pin >= 0) | |
425 | static void sport_set_termios(struct uart_port *port, | 448 | free_irq(gpio_to_irq(up->cts_pin), up); |
426 | struct ktermios *termios, struct ktermios *old) | 449 | #endif |
427 | { | ||
428 | pr_debug("%s enter, c_cflag:%08x\n", __func__, termios->c_cflag); | ||
429 | uart_update_timeout(port, CS8 ,port->uartclk); | ||
430 | } | 450 | } |
431 | 451 | ||
432 | static const char *sport_type(struct uart_port *port) | 452 | static const char *sport_type(struct uart_port *port) |
@@ -434,7 +454,7 @@ static const char *sport_type(struct uart_port *port) | |||
434 | struct sport_uart_port *up = (struct sport_uart_port *)port; | 454 | struct sport_uart_port *up = (struct sport_uart_port *)port; |
435 | 455 | ||
436 | pr_debug("%s enter\n", __func__); | 456 | pr_debug("%s enter\n", __func__); |
437 | return up->name; | 457 | return up->port.type == PORT_BFIN_SPORT ? "BFIN-SPORT-UART" : NULL; |
438 | } | 458 | } |
439 | 459 | ||
440 | static void sport_release_port(struct uart_port *port) | 460 | static void sport_release_port(struct uart_port *port) |
@@ -462,6 +482,95 @@ static int sport_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
462 | return 0; | 482 | return 0; |
463 | } | 483 | } |
464 | 484 | ||
485 | static void sport_set_termios(struct uart_port *port, | ||
486 | struct ktermios *termios, struct ktermios *old) | ||
487 | { | ||
488 | struct sport_uart_port *up = (struct sport_uart_port *)port; | ||
489 | unsigned long flags; | ||
490 | int i; | ||
491 | |||
492 | pr_debug("%s enter, c_cflag:%08x\n", __func__, termios->c_cflag); | ||
493 | |||
494 | switch (termios->c_cflag & CSIZE) { | ||
495 | case CS8: | ||
496 | up->csize = 8; | ||
497 | break; | ||
498 | case CS7: | ||
499 | up->csize = 7; | ||
500 | break; | ||
501 | case CS6: | ||
502 | up->csize = 6; | ||
503 | break; | ||
504 | case CS5: | ||
505 | up->csize = 5; | ||
506 | break; | ||
507 | default: | ||
508 | pr_warning("requested word length not supported\n"); | ||
509 | } | ||
510 | |||
511 | if (termios->c_cflag & CSTOPB) { | ||
512 | up->stopb = 1; | ||
513 | } | ||
514 | if (termios->c_cflag & PARENB) { | ||
515 | pr_warning("PAREN bits is not supported yet\n"); | ||
516 | /* up->parib = 1; */ | ||
517 | } | ||
518 | |||
519 | spin_lock_irqsave(&up->port.lock, flags); | ||
520 | |||
521 | port->read_status_mask = 0; | ||
522 | |||
523 | /* | ||
524 | * Characters to ignore | ||
525 | */ | ||
526 | port->ignore_status_mask = 0; | ||
527 | |||
528 | /* RX extract mask */ | ||
529 | up->rxmask = 0x01 | (((up->csize + up->stopb) * 2 - 1) << 0x8); | ||
530 | /* TX masks, 8 bit data and 1 bit stop for example: | ||
531 | * mask1 = b#0111111110 | ||
532 | * mask2 = b#1000000000 | ||
533 | */ | ||
534 | for (i = 0, up->txmask1 = 0; i < up->csize; i++) | ||
535 | up->txmask1 |= (1<<i); | ||
536 | up->txmask2 = (1<<i); | ||
537 | if (up->stopb) { | ||
538 | ++i; | ||
539 | up->txmask2 |= (1<<i); | ||
540 | } | ||
541 | up->txmask1 <<= 1; | ||
542 | up->txmask2 <<= 1; | ||
543 | /* uart baud rate */ | ||
544 | port->uartclk = uart_get_baud_rate(port, termios, old, 0, get_sclk()/16); | ||
545 | |||
546 | /* Disable UART */ | ||
547 | SPORT_PUT_TCR1(up, SPORT_GET_TCR1(up) & ~TSPEN); | ||
548 | SPORT_PUT_RCR1(up, SPORT_GET_RCR1(up) & ~RSPEN); | ||
549 | |||
550 | sport_uart_setup(up, up->csize + up->stopb, port->uartclk); | ||
551 | |||
552 | /* driver TX line high after config, one dummy data is | ||
553 | * necessary to stop sport after shift one byte | ||
554 | */ | ||
555 | SPORT_PUT_TX(up, 0xffff); | ||
556 | SPORT_PUT_TX(up, 0xffff); | ||
557 | SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) | TSPEN)); | ||
558 | SSYNC(); | ||
559 | while (!(SPORT_GET_STAT(up) & TXHRE)) | ||
560 | cpu_relax(); | ||
561 | SPORT_PUT_TCR1(up, SPORT_GET_TCR1(up) & ~TSPEN); | ||
562 | SSYNC(); | ||
563 | |||
564 | /* Port speed changed, update the per-port timeout. */ | ||
565 | uart_update_timeout(port, termios->c_cflag, port->uartclk); | ||
566 | |||
567 | /* Enable sport rx */ | ||
568 | SPORT_PUT_RCR1(up, SPORT_GET_RCR1(up) | RSPEN); | ||
569 | SSYNC(); | ||
570 | |||
571 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
572 | } | ||
573 | |||
465 | struct uart_ops sport_uart_ops = { | 574 | struct uart_ops sport_uart_ops = { |
466 | .tx_empty = sport_tx_empty, | 575 | .tx_empty = sport_tx_empty, |
467 | .set_mctrl = sport_set_mctrl, | 576 | .set_mctrl = sport_set_mctrl, |
@@ -481,138 +590,346 @@ struct uart_ops sport_uart_ops = { | |||
481 | .verify_port = sport_verify_port, | 590 | .verify_port = sport_verify_port, |
482 | }; | 591 | }; |
483 | 592 | ||
484 | static struct sport_uart_port sport_uart_ports[] = { | 593 | #define BFIN_SPORT_UART_MAX_PORTS 4 |
485 | { /* SPORT 0 */ | 594 | |
486 | .name = "SPORT0", | 595 | static struct sport_uart_port *bfin_sport_uart_ports[BFIN_SPORT_UART_MAX_PORTS]; |
487 | .tx_irq = IRQ_SPORT0_TX, | 596 | |
488 | .rx_irq = IRQ_SPORT0_RX, | 597 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE |
489 | .err_irq= IRQ_SPORT0_ERROR, | 598 | #define CLASS_BFIN_SPORT_CONSOLE "bfin-sport-console" |
490 | .port = { | 599 | |
491 | .type = PORT_BFIN_SPORT, | 600 | static int __init |
492 | .iotype = UPIO_MEM, | 601 | sport_uart_console_setup(struct console *co, char *options) |
493 | .membase = (void __iomem *)SPORT0_TCR1, | 602 | { |
494 | .mapbase = SPORT0_TCR1, | 603 | struct sport_uart_port *up; |
495 | .irq = IRQ_SPORT0_RX, | 604 | int baud = 57600; |
496 | .uartclk = CONFIG_SPORT_BAUD_RATE, | 605 | int bits = 8; |
497 | .fifosize = 8, | 606 | int parity = 'n'; |
498 | .ops = &sport_uart_ops, | 607 | # ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS |
499 | .line = 0, | 608 | int flow = 'r'; |
500 | }, | 609 | # else |
501 | }, { /* SPORT 1 */ | 610 | int flow = 'n'; |
502 | .name = "SPORT1", | 611 | # endif |
503 | .tx_irq = IRQ_SPORT1_TX, | 612 | |
504 | .rx_irq = IRQ_SPORT1_RX, | 613 | /* Check whether an invalid uart number has been specified */ |
505 | .err_irq= IRQ_SPORT1_ERROR, | 614 | if (co->index < 0 || co->index >= BFIN_SPORT_UART_MAX_PORTS) |
506 | .port = { | 615 | return -ENODEV; |
507 | .type = PORT_BFIN_SPORT, | 616 | |
508 | .iotype = UPIO_MEM, | 617 | up = bfin_sport_uart_ports[co->index]; |
509 | .membase = (void __iomem *)SPORT1_TCR1, | 618 | if (!up) |
510 | .mapbase = SPORT1_TCR1, | 619 | return -ENODEV; |
511 | .irq = IRQ_SPORT1_RX, | 620 | |
512 | .uartclk = CONFIG_SPORT_BAUD_RATE, | 621 | if (options) |
513 | .fifosize = 8, | 622 | uart_parse_options(options, &baud, &parity, &bits, &flow); |
514 | .ops = &sport_uart_ops, | 623 | |
515 | .line = 1, | 624 | return uart_set_options(&up->port, co, baud, parity, bits, flow); |
516 | }, | 625 | } |
626 | |||
627 | static void sport_uart_console_putchar(struct uart_port *port, int ch) | ||
628 | { | ||
629 | struct sport_uart_port *up = (struct sport_uart_port *)port; | ||
630 | |||
631 | while (SPORT_GET_STAT(up) & TXF) | ||
632 | barrier(); | ||
633 | |||
634 | tx_one_byte(up, ch); | ||
635 | } | ||
636 | |||
637 | /* | ||
638 | * Interrupts are disabled on entering | ||
639 | */ | ||
640 | static void | ||
641 | sport_uart_console_write(struct console *co, const char *s, unsigned int count) | ||
642 | { | ||
643 | struct sport_uart_port *up = bfin_sport_uart_ports[co->index]; | ||
644 | unsigned long flags; | ||
645 | |||
646 | spin_lock_irqsave(&up->port.lock, flags); | ||
647 | |||
648 | if (SPORT_GET_TCR1(up) & TSPEN) | ||
649 | uart_console_write(&up->port, s, count, sport_uart_console_putchar); | ||
650 | else { | ||
651 | /* dummy data to start sport */ | ||
652 | while (SPORT_GET_STAT(up) & TXF) | ||
653 | barrier(); | ||
654 | SPORT_PUT_TX(up, 0xffff); | ||
655 | /* Enable transmit, then an interrupt will generated */ | ||
656 | SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) | TSPEN)); | ||
657 | SSYNC(); | ||
658 | |||
659 | uart_console_write(&up->port, s, count, sport_uart_console_putchar); | ||
660 | |||
661 | /* Although the hold register is empty, last byte is still in shift | ||
662 | * register and not sent out yet. So, put a dummy data into TX FIFO. | ||
663 | * Then, sport tx stops when last byte is shift out and the dummy | ||
664 | * data is moved into the shift register. | ||
665 | */ | ||
666 | while (SPORT_GET_STAT(up) & TXF) | ||
667 | barrier(); | ||
668 | SPORT_PUT_TX(up, 0xffff); | ||
669 | while (!(SPORT_GET_STAT(up) & TXHRE)) | ||
670 | barrier(); | ||
671 | |||
672 | /* Stop sport tx transfer */ | ||
673 | SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) & ~TSPEN)); | ||
674 | SSYNC(); | ||
517 | } | 675 | } |
676 | |||
677 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
678 | } | ||
679 | |||
680 | static struct uart_driver sport_uart_reg; | ||
681 | |||
682 | static struct console sport_uart_console = { | ||
683 | .name = DEVICE_NAME, | ||
684 | .write = sport_uart_console_write, | ||
685 | .device = uart_console_device, | ||
686 | .setup = sport_uart_console_setup, | ||
687 | .flags = CON_PRINTBUFFER, | ||
688 | .index = -1, | ||
689 | .data = &sport_uart_reg, | ||
518 | }; | 690 | }; |
519 | 691 | ||
692 | #define SPORT_UART_CONSOLE (&sport_uart_console) | ||
693 | #else | ||
694 | #define SPORT_UART_CONSOLE NULL | ||
695 | #endif /* CONFIG_SERIAL_BFIN_SPORT_CONSOLE */ | ||
696 | |||
697 | |||
520 | static struct uart_driver sport_uart_reg = { | 698 | static struct uart_driver sport_uart_reg = { |
521 | .owner = THIS_MODULE, | 699 | .owner = THIS_MODULE, |
522 | .driver_name = "SPORT-UART", | 700 | .driver_name = DRV_NAME, |
523 | .dev_name = "ttySS", | 701 | .dev_name = DEVICE_NAME, |
524 | .major = 204, | 702 | .major = 204, |
525 | .minor = 84, | 703 | .minor = 84, |
526 | .nr = ARRAY_SIZE(sport_uart_ports), | 704 | .nr = BFIN_SPORT_UART_MAX_PORTS, |
527 | .cons = NULL, | 705 | .cons = SPORT_UART_CONSOLE, |
528 | }; | 706 | }; |
529 | 707 | ||
530 | static int sport_uart_suspend(struct platform_device *dev, pm_message_t state) | 708 | #ifdef CONFIG_PM |
709 | static int sport_uart_suspend(struct device *dev) | ||
531 | { | 710 | { |
532 | struct sport_uart_port *sport = platform_get_drvdata(dev); | 711 | struct sport_uart_port *sport = dev_get_drvdata(dev); |
533 | 712 | ||
534 | pr_debug("%s enter\n", __func__); | 713 | dev_dbg(dev, "%s enter\n", __func__); |
535 | if (sport) | 714 | if (sport) |
536 | uart_suspend_port(&sport_uart_reg, &sport->port); | 715 | uart_suspend_port(&sport_uart_reg, &sport->port); |
537 | 716 | ||
538 | return 0; | 717 | return 0; |
539 | } | 718 | } |
540 | 719 | ||
541 | static int sport_uart_resume(struct platform_device *dev) | 720 | static int sport_uart_resume(struct device *dev) |
542 | { | 721 | { |
543 | struct sport_uart_port *sport = platform_get_drvdata(dev); | 722 | struct sport_uart_port *sport = dev_get_drvdata(dev); |
544 | 723 | ||
545 | pr_debug("%s enter\n", __func__); | 724 | dev_dbg(dev, "%s enter\n", __func__); |
546 | if (sport) | 725 | if (sport) |
547 | uart_resume_port(&sport_uart_reg, &sport->port); | 726 | uart_resume_port(&sport_uart_reg, &sport->port); |
548 | 727 | ||
549 | return 0; | 728 | return 0; |
550 | } | 729 | } |
551 | 730 | ||
552 | static int sport_uart_probe(struct platform_device *dev) | 731 | static struct dev_pm_ops bfin_sport_uart_dev_pm_ops = { |
732 | .suspend = sport_uart_suspend, | ||
733 | .resume = sport_uart_resume, | ||
734 | }; | ||
735 | #endif | ||
736 | |||
737 | static int __devinit sport_uart_probe(struct platform_device *pdev) | ||
553 | { | 738 | { |
554 | pr_debug("%s enter\n", __func__); | 739 | struct resource *res; |
555 | sport_uart_ports[dev->id].port.dev = &dev->dev; | 740 | struct sport_uart_port *sport; |
556 | uart_add_one_port(&sport_uart_reg, &sport_uart_ports[dev->id].port); | 741 | int ret = 0; |
557 | platform_set_drvdata(dev, &sport_uart_ports[dev->id]); | ||
558 | 742 | ||
559 | return 0; | 743 | dev_dbg(&pdev->dev, "%s enter\n", __func__); |
744 | |||
745 | if (pdev->id < 0 || pdev->id >= BFIN_SPORT_UART_MAX_PORTS) { | ||
746 | dev_err(&pdev->dev, "Wrong sport uart platform device id.\n"); | ||
747 | return -ENOENT; | ||
748 | } | ||
749 | |||
750 | if (bfin_sport_uart_ports[pdev->id] == NULL) { | ||
751 | bfin_sport_uart_ports[pdev->id] = | ||
752 | kzalloc(sizeof(struct sport_uart_port), GFP_KERNEL); | ||
753 | sport = bfin_sport_uart_ports[pdev->id]; | ||
754 | if (!sport) { | ||
755 | dev_err(&pdev->dev, | ||
756 | "Fail to malloc sport_uart_port\n"); | ||
757 | return -ENOMEM; | ||
758 | } | ||
759 | |||
760 | ret = peripheral_request_list( | ||
761 | (unsigned short *)pdev->dev.platform_data, DRV_NAME); | ||
762 | if (ret) { | ||
763 | dev_err(&pdev->dev, | ||
764 | "Fail to request SPORT peripherals\n"); | ||
765 | goto out_error_free_mem; | ||
766 | } | ||
767 | |||
768 | spin_lock_init(&sport->port.lock); | ||
769 | sport->port.fifosize = SPORT_TX_FIFO_SIZE, | ||
770 | sport->port.ops = &sport_uart_ops; | ||
771 | sport->port.line = pdev->id; | ||
772 | sport->port.iotype = UPIO_MEM; | ||
773 | sport->port.flags = UPF_BOOT_AUTOCONF; | ||
774 | |||
775 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
776 | if (res == NULL) { | ||
777 | dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n"); | ||
778 | ret = -ENOENT; | ||
779 | goto out_error_free_peripherals; | ||
780 | } | ||
781 | |||
782 | sport->port.membase = ioremap(res->start, resource_size(res)); | ||
783 | if (!sport->port.membase) { | ||
784 | dev_err(&pdev->dev, "Cannot map sport IO\n"); | ||
785 | ret = -ENXIO; | ||
786 | goto out_error_free_peripherals; | ||
787 | } | ||
788 | sport->port.mapbase = res->start; | ||
789 | |||
790 | sport->port.irq = platform_get_irq(pdev, 0); | ||
791 | if (sport->port.irq < 0) { | ||
792 | dev_err(&pdev->dev, "No sport RX/TX IRQ specified\n"); | ||
793 | ret = -ENOENT; | ||
794 | goto out_error_unmap; | ||
795 | } | ||
796 | |||
797 | sport->err_irq = platform_get_irq(pdev, 1); | ||
798 | if (sport->err_irq < 0) { | ||
799 | dev_err(&pdev->dev, "No sport status IRQ specified\n"); | ||
800 | ret = -ENOENT; | ||
801 | goto out_error_unmap; | ||
802 | } | ||
803 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS | ||
804 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | ||
805 | if (res == NULL) | ||
806 | sport->cts_pin = -1; | ||
807 | else | ||
808 | sport->cts_pin = res->start; | ||
809 | |||
810 | res = platform_get_resource(pdev, IORESOURCE_IO, 1); | ||
811 | if (res == NULL) | ||
812 | sport->rts_pin = -1; | ||
813 | else | ||
814 | sport->rts_pin = res->start; | ||
815 | |||
816 | if (sport->rts_pin >= 0) | ||
817 | gpio_request(sport->rts_pin, DRV_NAME); | ||
818 | #endif | ||
819 | } | ||
820 | |||
821 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE | ||
822 | if (!is_early_platform_device(pdev)) { | ||
823 | #endif | ||
824 | sport = bfin_sport_uart_ports[pdev->id]; | ||
825 | sport->port.dev = &pdev->dev; | ||
826 | dev_set_drvdata(&pdev->dev, sport); | ||
827 | ret = uart_add_one_port(&sport_uart_reg, &sport->port); | ||
828 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE | ||
829 | } | ||
830 | #endif | ||
831 | if (!ret) | ||
832 | return 0; | ||
833 | |||
834 | if (sport) { | ||
835 | out_error_unmap: | ||
836 | iounmap(sport->port.membase); | ||
837 | out_error_free_peripherals: | ||
838 | peripheral_free_list( | ||
839 | (unsigned short *)pdev->dev.platform_data); | ||
840 | out_error_free_mem: | ||
841 | kfree(sport); | ||
842 | bfin_sport_uart_ports[pdev->id] = NULL; | ||
843 | } | ||
844 | |||
845 | return ret; | ||
560 | } | 846 | } |
561 | 847 | ||
562 | static int sport_uart_remove(struct platform_device *dev) | 848 | static int __devexit sport_uart_remove(struct platform_device *pdev) |
563 | { | 849 | { |
564 | struct sport_uart_port *sport = platform_get_drvdata(dev); | 850 | struct sport_uart_port *sport = platform_get_drvdata(pdev); |
565 | 851 | ||
566 | pr_debug("%s enter\n", __func__); | 852 | dev_dbg(&pdev->dev, "%s enter\n", __func__); |
567 | platform_set_drvdata(dev, NULL); | 853 | dev_set_drvdata(&pdev->dev, NULL); |
568 | 854 | ||
569 | if (sport) | 855 | if (sport) { |
570 | uart_remove_one_port(&sport_uart_reg, &sport->port); | 856 | uart_remove_one_port(&sport_uart_reg, &sport->port); |
857 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
858 | if (sport->rts_pin >= 0) | ||
859 | gpio_free(sport->rts_pin); | ||
860 | #endif | ||
861 | iounmap(sport->port.membase); | ||
862 | peripheral_free_list( | ||
863 | (unsigned short *)pdev->dev.platform_data); | ||
864 | kfree(sport); | ||
865 | bfin_sport_uart_ports[pdev->id] = NULL; | ||
866 | } | ||
571 | 867 | ||
572 | return 0; | 868 | return 0; |
573 | } | 869 | } |
574 | 870 | ||
575 | static struct platform_driver sport_uart_driver = { | 871 | static struct platform_driver sport_uart_driver = { |
576 | .probe = sport_uart_probe, | 872 | .probe = sport_uart_probe, |
577 | .remove = sport_uart_remove, | 873 | .remove = __devexit_p(sport_uart_remove), |
578 | .suspend = sport_uart_suspend, | ||
579 | .resume = sport_uart_resume, | ||
580 | .driver = { | 874 | .driver = { |
581 | .name = DRV_NAME, | 875 | .name = DRV_NAME, |
876 | #ifdef CONFIG_PM | ||
877 | .pm = &bfin_sport_uart_dev_pm_ops, | ||
878 | #endif | ||
582 | }, | 879 | }, |
583 | }; | 880 | }; |
584 | 881 | ||
882 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE | ||
883 | static __initdata struct early_platform_driver early_sport_uart_driver = { | ||
884 | .class_str = CLASS_BFIN_SPORT_CONSOLE, | ||
885 | .pdrv = &sport_uart_driver, | ||
886 | .requested_id = EARLY_PLATFORM_ID_UNSET, | ||
887 | }; | ||
888 | |||
889 | static int __init sport_uart_rs_console_init(void) | ||
890 | { | ||
891 | early_platform_driver_register(&early_sport_uart_driver, DRV_NAME); | ||
892 | |||
893 | early_platform_driver_probe(CLASS_BFIN_SPORT_CONSOLE, | ||
894 | BFIN_SPORT_UART_MAX_PORTS, 0); | ||
895 | |||
896 | register_console(&sport_uart_console); | ||
897 | |||
898 | return 0; | ||
899 | } | ||
900 | console_initcall(sport_uart_rs_console_init); | ||
901 | #endif | ||
902 | |||
585 | static int __init sport_uart_init(void) | 903 | static int __init sport_uart_init(void) |
586 | { | 904 | { |
587 | int ret; | 905 | int ret; |
588 | 906 | ||
589 | pr_debug("%s enter\n", __func__); | 907 | pr_info("Blackfin uart over sport driver\n"); |
908 | |||
590 | ret = uart_register_driver(&sport_uart_reg); | 909 | ret = uart_register_driver(&sport_uart_reg); |
591 | if (ret != 0) { | 910 | if (ret) { |
592 | printk(KERN_ERR "Failed to register %s:%d\n", | 911 | pr_err("failed to register %s:%d\n", |
593 | sport_uart_reg.driver_name, ret); | 912 | sport_uart_reg.driver_name, ret); |
594 | return ret; | 913 | return ret; |
595 | } | 914 | } |
596 | 915 | ||
597 | ret = platform_driver_register(&sport_uart_driver); | 916 | ret = platform_driver_register(&sport_uart_driver); |
598 | if (ret != 0) { | 917 | if (ret) { |
599 | printk(KERN_ERR "Failed to register sport uart driver:%d\n", ret); | 918 | pr_err("failed to register sport uart driver:%d\n", ret); |
600 | uart_unregister_driver(&sport_uart_reg); | 919 | uart_unregister_driver(&sport_uart_reg); |
601 | } | 920 | } |
602 | 921 | ||
603 | |||
604 | pr_debug("%s exit\n", __func__); | ||
605 | return ret; | 922 | return ret; |
606 | } | 923 | } |
924 | module_init(sport_uart_init); | ||
607 | 925 | ||
608 | static void __exit sport_uart_exit(void) | 926 | static void __exit sport_uart_exit(void) |
609 | { | 927 | { |
610 | pr_debug("%s enter\n", __func__); | ||
611 | platform_driver_unregister(&sport_uart_driver); | 928 | platform_driver_unregister(&sport_uart_driver); |
612 | uart_unregister_driver(&sport_uart_reg); | 929 | uart_unregister_driver(&sport_uart_reg); |
613 | } | 930 | } |
614 | |||
615 | module_init(sport_uart_init); | ||
616 | module_exit(sport_uart_exit); | 931 | module_exit(sport_uart_exit); |
617 | 932 | ||
933 | MODULE_AUTHOR("Sonic Zhang, Roy Huang"); | ||
934 | MODULE_DESCRIPTION("Blackfin serial over SPORT driver"); | ||
618 | MODULE_LICENSE("GPL"); | 935 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/serial/bfin_sport_uart.h b/drivers/serial/bfin_sport_uart.h index 671d41cc1a3f..6d06ce1d5675 100644 --- a/drivers/serial/bfin_sport_uart.h +++ b/drivers/serial/bfin_sport_uart.h | |||
@@ -1,29 +1,23 @@ | |||
1 | /* | 1 | /* |
2 | * File: linux/drivers/serial/bfin_sport_uart.h | 2 | * Blackfin On-Chip Sport Emulated UART Driver |
3 | * | 3 | * |
4 | * Based on: include/asm-blackfin/mach-533/bfin_serial_5xx.h | 4 | * Copyright 2006-2008 Analog Devices Inc. |
5 | * Author: Roy Huang <roy.huang>analog.com> | ||
6 | * | 5 | * |
7 | * Created: Nov 22, 2006 | 6 | * Enter bugs at http://blackfin.uclinux.org/ |
8 | * Copyright: (C) Analog Device Inc. | ||
9 | * Description: this driver enable SPORTs on Blackfin emulate UART. | ||
10 | * | 7 | * |
11 | * This program is free software; you can redistribute it and/or modify | 8 | * Licensed under the GPL-2 or later. |
12 | * it under the terms of the GNU General Public License as published by | 9 | */ |
13 | * the Free Software Foundation; either version 2 of the License, or | 10 | |
14 | * (at your option) any later version. | 11 | /* |
15 | * | 12 | * This driver and the hardware supported are in term of EE-191 of ADI. |
16 | * This program is distributed in the hope that it will be useful, | 13 | * http://www.analog.com/static/imported-files/application_notes/EE191.pdf |
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 | * This application note describe how to implement a UART on a Sharc DSP, |
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 15 | * but this driver is implemented on Blackfin Processor. |
19 | * GNU General Public License for more details. | 16 | * Transmit Frame Sync is not used by this driver to transfer data out. |
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, see the file COPYING, or write | ||
23 | * to the Free Software Foundation, Inc., | ||
24 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
25 | */ | 17 | */ |
26 | 18 | ||
19 | #ifndef _BFIN_SPORT_UART_H | ||
20 | #define _BFIN_SPORT_UART_H | ||
27 | 21 | ||
28 | #define OFFSET_TCR1 0x00 /* Transmit Configuration 1 Register */ | 22 | #define OFFSET_TCR1 0x00 /* Transmit Configuration 1 Register */ |
29 | #define OFFSET_TCR2 0x04 /* Transmit Configuration 2 Register */ | 23 | #define OFFSET_TCR2 0x04 /* Transmit Configuration 2 Register */ |
@@ -43,7 +37,21 @@ | |||
43 | #define SPORT_GET_TFSDIV(sport) bfin_read16(((sport)->port.membase + OFFSET_TFSDIV)) | 37 | #define SPORT_GET_TFSDIV(sport) bfin_read16(((sport)->port.membase + OFFSET_TFSDIV)) |
44 | #define SPORT_GET_TX(sport) bfin_read16(((sport)->port.membase + OFFSET_TX)) | 38 | #define SPORT_GET_TX(sport) bfin_read16(((sport)->port.membase + OFFSET_TX)) |
45 | #define SPORT_GET_RX(sport) bfin_read16(((sport)->port.membase + OFFSET_RX)) | 39 | #define SPORT_GET_RX(sport) bfin_read16(((sport)->port.membase + OFFSET_RX)) |
46 | #define SPORT_GET_RX32(sport) bfin_read32(((sport)->port.membase + OFFSET_RX)) | 40 | /* |
41 | * If another interrupt fires while doing a 32-bit read from RX FIFO, | ||
42 | * a fake RX underflow error will be generated. So disable interrupts | ||
43 | * to prevent interruption while reading the FIFO. | ||
44 | */ | ||
45 | #define SPORT_GET_RX32(sport) \ | ||
46 | ({ \ | ||
47 | unsigned int __ret; \ | ||
48 | if (ANOMALY_05000473) \ | ||
49 | local_irq_disable(); \ | ||
50 | __ret = bfin_read32((sport)->port.membase + OFFSET_RX); \ | ||
51 | if (ANOMALY_05000473) \ | ||
52 | local_irq_enable(); \ | ||
53 | __ret; \ | ||
54 | }) | ||
47 | #define SPORT_GET_RCR1(sport) bfin_read16(((sport)->port.membase + OFFSET_RCR1)) | 55 | #define SPORT_GET_RCR1(sport) bfin_read16(((sport)->port.membase + OFFSET_RCR1)) |
48 | #define SPORT_GET_RCR2(sport) bfin_read16(((sport)->port.membase + OFFSET_RCR2)) | 56 | #define SPORT_GET_RCR2(sport) bfin_read16(((sport)->port.membase + OFFSET_RCR2)) |
49 | #define SPORT_GET_RCLKDIV(sport) bfin_read16(((sport)->port.membase + OFFSET_RCLKDIV)) | 57 | #define SPORT_GET_RCLKDIV(sport) bfin_read16(((sport)->port.membase + OFFSET_RCLKDIV)) |
@@ -61,3 +69,18 @@ | |||
61 | #define SPORT_PUT_RCLKDIV(sport, v) bfin_write16(((sport)->port.membase + OFFSET_RCLKDIV), v) | 69 | #define SPORT_PUT_RCLKDIV(sport, v) bfin_write16(((sport)->port.membase + OFFSET_RCLKDIV), v) |
62 | #define SPORT_PUT_RFSDIV(sport, v) bfin_write16(((sport)->port.membase + OFFSET_RFSDIV), v) | 70 | #define SPORT_PUT_RFSDIV(sport, v) bfin_write16(((sport)->port.membase + OFFSET_RFSDIV), v) |
63 | #define SPORT_PUT_STAT(sport, v) bfin_write16(((sport)->port.membase + OFFSET_STAT), v) | 71 | #define SPORT_PUT_STAT(sport, v) bfin_write16(((sport)->port.membase + OFFSET_STAT), v) |
72 | |||
73 | #define SPORT_TX_FIFO_SIZE 8 | ||
74 | |||
75 | #define SPORT_UART_GET_CTS(x) gpio_get_value(x->cts_pin) | ||
76 | #define SPORT_UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1) | ||
77 | #define SPORT_UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0) | ||
78 | |||
79 | #if defined(CONFIG_SERIAL_BFIN_SPORT0_UART_CTSRTS) \ | ||
80 | || defined(CONFIG_SERIAL_BFIN_SPORT1_UART_CTSRTS) \ | ||
81 | || defined(CONFIG_SERIAL_BFIN_SPORT2_UART_CTSRTS) \ | ||
82 | || defined(CONFIG_SERIAL_BFIN_SPORT3_UART_CTSRTS) | ||
83 | # define CONFIG_SERIAL_BFIN_SPORT_CTSRTS | ||
84 | #endif | ||
85 | |||
86 | #endif /* _BFIN_SPORT_UART_H */ | ||
diff --git a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c index 80e76426131d..b6acd19b458e 100644 --- a/drivers/serial/clps711x.c +++ b/drivers/serial/clps711x.c | |||
@@ -93,7 +93,7 @@ static void clps711xuart_enable_ms(struct uart_port *port) | |||
93 | static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id) | 93 | static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id) |
94 | { | 94 | { |
95 | struct uart_port *port = dev_id; | 95 | struct uart_port *port = dev_id; |
96 | struct tty_struct *tty = port->info->port.tty; | 96 | struct tty_struct *tty = port->state->port.tty; |
97 | unsigned int status, ch, flg; | 97 | unsigned int status, ch, flg; |
98 | 98 | ||
99 | status = clps_readl(SYSFLG(port)); | 99 | status = clps_readl(SYSFLG(port)); |
@@ -147,7 +147,7 @@ static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id) | |||
147 | static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id) | 147 | static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id) |
148 | { | 148 | { |
149 | struct uart_port *port = dev_id; | 149 | struct uart_port *port = dev_id; |
150 | struct circ_buf *xmit = &port->info->xmit; | 150 | struct circ_buf *xmit = &port->state->xmit; |
151 | int count; | 151 | int count; |
152 | 152 | ||
153 | if (port->x_char) { | 153 | if (port->x_char) { |
diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h index 7274b527a3c1..b754dcf0fda5 100644 --- a/drivers/serial/cpm_uart/cpm_uart.h +++ b/drivers/serial/cpm_uart/cpm_uart.h | |||
@@ -76,18 +76,12 @@ struct uart_cpm_port { | |||
76 | unsigned char *tx_buf; | 76 | unsigned char *tx_buf; |
77 | unsigned char *rx_buf; | 77 | unsigned char *rx_buf; |
78 | u32 flags; | 78 | u32 flags; |
79 | void (*set_lineif)(struct uart_cpm_port *); | ||
80 | struct clk *clk; | 79 | struct clk *clk; |
81 | u8 brg; | 80 | u8 brg; |
82 | uint dp_addr; | 81 | uint dp_addr; |
83 | void *mem_addr; | 82 | void *mem_addr; |
84 | dma_addr_t dma_addr; | 83 | dma_addr_t dma_addr; |
85 | u32 mem_size; | 84 | u32 mem_size; |
86 | /* helpers */ | ||
87 | int baud; | ||
88 | int bits; | ||
89 | /* Keep track of 'odd' SMC2 wirings */ | ||
90 | int is_portb; | ||
91 | /* wait on close if needed */ | 85 | /* wait on close if needed */ |
92 | int wait_closing; | 86 | int wait_closing; |
93 | /* value to combine with opcode to form cpm command */ | 87 | /* value to combine with opcode to form cpm command */ |
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index f8df0681e160..8692ff98fc07 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c | |||
@@ -72,6 +72,8 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo); | |||
72 | 72 | ||
73 | /**************************************************************/ | 73 | /**************************************************************/ |
74 | 74 | ||
75 | #define HW_BUF_SPD_THRESHOLD 9600 | ||
76 | |||
75 | /* | 77 | /* |
76 | * Check, if transmit buffers are processed | 78 | * Check, if transmit buffers are processed |
77 | */ | 79 | */ |
@@ -244,7 +246,7 @@ static void cpm_uart_int_rx(struct uart_port *port) | |||
244 | int i; | 246 | int i; |
245 | unsigned char ch; | 247 | unsigned char ch; |
246 | u8 *cp; | 248 | u8 *cp; |
247 | struct tty_struct *tty = port->info->port.tty; | 249 | struct tty_struct *tty = port->state->port.tty; |
248 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | 250 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; |
249 | cbd_t __iomem *bdp; | 251 | cbd_t __iomem *bdp; |
250 | u16 status; | 252 | u16 status; |
@@ -503,6 +505,11 @@ static void cpm_uart_set_termios(struct uart_port *port, | |||
503 | pr_debug("CPM uart[%d]:set_termios\n", port->line); | 505 | pr_debug("CPM uart[%d]:set_termios\n", port->line); |
504 | 506 | ||
505 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); | 507 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); |
508 | if (baud <= HW_BUF_SPD_THRESHOLD || | ||
509 | (pinfo->port.state && pinfo->port.state->port.tty->low_latency)) | ||
510 | pinfo->rx_fifosize = 1; | ||
511 | else | ||
512 | pinfo->rx_fifosize = RX_BUF_SIZE; | ||
506 | 513 | ||
507 | /* Character length programmed into the mode register is the | 514 | /* Character length programmed into the mode register is the |
508 | * sum of: 1 start bit, number of data bits, 0 or 1 parity bit, | 515 | * sum of: 1 start bit, number of data bits, 0 or 1 parity bit, |
@@ -594,6 +601,17 @@ static void cpm_uart_set_termios(struct uart_port *port, | |||
594 | */ | 601 | */ |
595 | bits++; | 602 | bits++; |
596 | if (IS_SMC(pinfo)) { | 603 | if (IS_SMC(pinfo)) { |
604 | /* | ||
605 | * MRBLR can be changed while an SMC/SCC is operating only | ||
606 | * if it is done in a single bus cycle with one 16-bit move | ||
607 | * (not two 8-bit bus cycles back-to-back). This occurs when | ||
608 | * the cp shifts control to the next RxBD, so the change does | ||
609 | * not take effect immediately. To guarantee the exact RxBD | ||
610 | * on which the change occurs, change MRBLR only while the | ||
611 | * SMC/SCC receiver is disabled. | ||
612 | */ | ||
613 | out_be16(&pinfo->smcup->smc_mrblr, pinfo->rx_fifosize); | ||
614 | |||
597 | /* Set the mode register. We want to keep a copy of the | 615 | /* Set the mode register. We want to keep a copy of the |
598 | * enables, because we want to put them back if they were | 616 | * enables, because we want to put them back if they were |
599 | * present. | 617 | * present. |
@@ -604,6 +622,7 @@ static void cpm_uart_set_termios(struct uart_port *port, | |||
604 | out_be16(&smcp->smc_smcmr, smcr_mk_clen(bits) | cval | | 622 | out_be16(&smcp->smc_smcmr, smcr_mk_clen(bits) | cval | |
605 | SMCMR_SM_UART | prev_mode); | 623 | SMCMR_SM_UART | prev_mode); |
606 | } else { | 624 | } else { |
625 | out_be16(&pinfo->sccup->scc_genscc.scc_mrblr, pinfo->rx_fifosize); | ||
607 | out_be16(&sccp->scc_psmr, (sbits << 12) | scval); | 626 | out_be16(&sccp->scc_psmr, (sbits << 12) | scval); |
608 | } | 627 | } |
609 | 628 | ||
@@ -649,7 +668,7 @@ static int cpm_uart_tx_pump(struct uart_port *port) | |||
649 | u8 *p; | 668 | u8 *p; |
650 | int count; | 669 | int count; |
651 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | 670 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; |
652 | struct circ_buf *xmit = &port->info->xmit; | 671 | struct circ_buf *xmit = &port->state->xmit; |
653 | 672 | ||
654 | /* Handle xon/xoff */ | 673 | /* Handle xon/xoff */ |
655 | if (port->x_char) { | 674 | if (port->x_char) { |
@@ -852,7 +871,7 @@ static void cpm_uart_init_smc(struct uart_cpm_port *pinfo) | |||
852 | */ | 871 | */ |
853 | cpm_set_smc_fcr(up); | 872 | cpm_set_smc_fcr(up); |
854 | 873 | ||
855 | /* Using idle charater time requires some additional tuning. */ | 874 | /* Using idle character time requires some additional tuning. */ |
856 | out_be16(&up->smc_mrblr, pinfo->rx_fifosize); | 875 | out_be16(&up->smc_mrblr, pinfo->rx_fifosize); |
857 | out_be16(&up->smc_maxidl, pinfo->rx_fifosize); | 876 | out_be16(&up->smc_maxidl, pinfo->rx_fifosize); |
858 | out_be16(&up->smc_brklen, 0); | 877 | out_be16(&up->smc_brklen, 0); |
@@ -930,6 +949,83 @@ static void cpm_uart_config_port(struct uart_port *port, int flags) | |||
930 | } | 949 | } |
931 | } | 950 | } |
932 | 951 | ||
952 | #if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_CPM_CONSOLE) | ||
953 | /* | ||
954 | * Write a string to the serial port | ||
955 | * Note that this is called with interrupts already disabled | ||
956 | */ | ||
957 | static void cpm_uart_early_write(struct uart_cpm_port *pinfo, | ||
958 | const char *string, u_int count) | ||
959 | { | ||
960 | unsigned int i; | ||
961 | cbd_t __iomem *bdp, *bdbase; | ||
962 | unsigned char *cpm_outp_addr; | ||
963 | |||
964 | /* Get the address of the host memory buffer. | ||
965 | */ | ||
966 | bdp = pinfo->tx_cur; | ||
967 | bdbase = pinfo->tx_bd_base; | ||
968 | |||
969 | /* | ||
970 | * Now, do each character. This is not as bad as it looks | ||
971 | * since this is a holding FIFO and not a transmitting FIFO. | ||
972 | * We could add the complexity of filling the entire transmit | ||
973 | * buffer, but we would just wait longer between accesses...... | ||
974 | */ | ||
975 | for (i = 0; i < count; i++, string++) { | ||
976 | /* Wait for transmitter fifo to empty. | ||
977 | * Ready indicates output is ready, and xmt is doing | ||
978 | * that, not that it is ready for us to send. | ||
979 | */ | ||
980 | while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) | ||
981 | ; | ||
982 | |||
983 | /* Send the character out. | ||
984 | * If the buffer address is in the CPM DPRAM, don't | ||
985 | * convert it. | ||
986 | */ | ||
987 | cpm_outp_addr = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), | ||
988 | pinfo); | ||
989 | *cpm_outp_addr = *string; | ||
990 | |||
991 | out_be16(&bdp->cbd_datlen, 1); | ||
992 | setbits16(&bdp->cbd_sc, BD_SC_READY); | ||
993 | |||
994 | if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) | ||
995 | bdp = bdbase; | ||
996 | else | ||
997 | bdp++; | ||
998 | |||
999 | /* if a LF, also do CR... */ | ||
1000 | if (*string == 10) { | ||
1001 | while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) | ||
1002 | ; | ||
1003 | |||
1004 | cpm_outp_addr = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), | ||
1005 | pinfo); | ||
1006 | *cpm_outp_addr = 13; | ||
1007 | |||
1008 | out_be16(&bdp->cbd_datlen, 1); | ||
1009 | setbits16(&bdp->cbd_sc, BD_SC_READY); | ||
1010 | |||
1011 | if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) | ||
1012 | bdp = bdbase; | ||
1013 | else | ||
1014 | bdp++; | ||
1015 | } | ||
1016 | } | ||
1017 | |||
1018 | /* | ||
1019 | * Finally, Wait for transmitter & holding register to empty | ||
1020 | * and restore the IER | ||
1021 | */ | ||
1022 | while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) | ||
1023 | ; | ||
1024 | |||
1025 | pinfo->tx_cur = bdp; | ||
1026 | } | ||
1027 | #endif | ||
1028 | |||
933 | #ifdef CONFIG_CONSOLE_POLL | 1029 | #ifdef CONFIG_CONSOLE_POLL |
934 | /* Serial polling routines for writing and reading from the uart while | 1030 | /* Serial polling routines for writing and reading from the uart while |
935 | * in an interrupt or debug context. | 1031 | * in an interrupt or debug context. |
@@ -999,7 +1095,7 @@ static void cpm_put_poll_char(struct uart_port *port, | |||
999 | static char ch[2]; | 1095 | static char ch[2]; |
1000 | 1096 | ||
1001 | ch[0] = (char)c; | 1097 | ch[0] = (char)c; |
1002 | cpm_uart_early_write(pinfo->port.line, ch, 1); | 1098 | cpm_uart_early_write(pinfo, ch, 1); |
1003 | } | 1099 | } |
1004 | #endif /* CONFIG_CONSOLE_POLL */ | 1100 | #endif /* CONFIG_CONSOLE_POLL */ |
1005 | 1101 | ||
@@ -1130,9 +1226,6 @@ static void cpm_uart_console_write(struct console *co, const char *s, | |||
1130 | u_int count) | 1226 | u_int count) |
1131 | { | 1227 | { |
1132 | struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index]; | 1228 | struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index]; |
1133 | unsigned int i; | ||
1134 | cbd_t __iomem *bdp, *bdbase; | ||
1135 | unsigned char *cp; | ||
1136 | unsigned long flags; | 1229 | unsigned long flags; |
1137 | int nolock = oops_in_progress; | 1230 | int nolock = oops_in_progress; |
1138 | 1231 | ||
@@ -1142,66 +1235,7 @@ static void cpm_uart_console_write(struct console *co, const char *s, | |||
1142 | spin_lock_irqsave(&pinfo->port.lock, flags); | 1235 | spin_lock_irqsave(&pinfo->port.lock, flags); |
1143 | } | 1236 | } |
1144 | 1237 | ||
1145 | /* Get the address of the host memory buffer. | 1238 | cpm_uart_early_write(pinfo, s, count); |
1146 | */ | ||
1147 | bdp = pinfo->tx_cur; | ||
1148 | bdbase = pinfo->tx_bd_base; | ||
1149 | |||
1150 | /* | ||
1151 | * Now, do each character. This is not as bad as it looks | ||
1152 | * since this is a holding FIFO and not a transmitting FIFO. | ||
1153 | * We could add the complexity of filling the entire transmit | ||
1154 | * buffer, but we would just wait longer between accesses...... | ||
1155 | */ | ||
1156 | for (i = 0; i < count; i++, s++) { | ||
1157 | /* Wait for transmitter fifo to empty. | ||
1158 | * Ready indicates output is ready, and xmt is doing | ||
1159 | * that, not that it is ready for us to send. | ||
1160 | */ | ||
1161 | while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) | ||
1162 | ; | ||
1163 | |||
1164 | /* Send the character out. | ||
1165 | * If the buffer address is in the CPM DPRAM, don't | ||
1166 | * convert it. | ||
1167 | */ | ||
1168 | cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); | ||
1169 | *cp = *s; | ||
1170 | |||
1171 | out_be16(&bdp->cbd_datlen, 1); | ||
1172 | setbits16(&bdp->cbd_sc, BD_SC_READY); | ||
1173 | |||
1174 | if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) | ||
1175 | bdp = bdbase; | ||
1176 | else | ||
1177 | bdp++; | ||
1178 | |||
1179 | /* if a LF, also do CR... */ | ||
1180 | if (*s == 10) { | ||
1181 | while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) | ||
1182 | ; | ||
1183 | |||
1184 | cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); | ||
1185 | *cp = 13; | ||
1186 | |||
1187 | out_be16(&bdp->cbd_datlen, 1); | ||
1188 | setbits16(&bdp->cbd_sc, BD_SC_READY); | ||
1189 | |||
1190 | if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) | ||
1191 | bdp = bdbase; | ||
1192 | else | ||
1193 | bdp++; | ||
1194 | } | ||
1195 | } | ||
1196 | |||
1197 | /* | ||
1198 | * Finally, Wait for transmitter & holding register to empty | ||
1199 | * and restore the IER | ||
1200 | */ | ||
1201 | while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) | ||
1202 | ; | ||
1203 | |||
1204 | pinfo->tx_cur = bdp; | ||
1205 | 1239 | ||
1206 | if (unlikely(nolock)) { | 1240 | if (unlikely(nolock)) { |
1207 | local_irq_restore(flags); | 1241 | local_irq_restore(flags); |
@@ -1325,7 +1359,7 @@ static struct uart_driver cpm_reg = { | |||
1325 | 1359 | ||
1326 | static int probe_index; | 1360 | static int probe_index; |
1327 | 1361 | ||
1328 | static int __devinit cpm_uart_probe(struct of_device *ofdev, | 1362 | static int __devinit cpm_uart_probe(struct platform_device *ofdev, |
1329 | const struct of_device_id *match) | 1363 | const struct of_device_id *match) |
1330 | { | 1364 | { |
1331 | int index = probe_index++; | 1365 | int index = probe_index++; |
@@ -1342,14 +1376,14 @@ static int __devinit cpm_uart_probe(struct of_device *ofdev, | |||
1342 | /* initialize the device pointer for the port */ | 1376 | /* initialize the device pointer for the port */ |
1343 | pinfo->port.dev = &ofdev->dev; | 1377 | pinfo->port.dev = &ofdev->dev; |
1344 | 1378 | ||
1345 | ret = cpm_uart_init_port(ofdev->node, pinfo); | 1379 | ret = cpm_uart_init_port(ofdev->dev.of_node, pinfo); |
1346 | if (ret) | 1380 | if (ret) |
1347 | return ret; | 1381 | return ret; |
1348 | 1382 | ||
1349 | return uart_add_one_port(&cpm_reg, &pinfo->port); | 1383 | return uart_add_one_port(&cpm_reg, &pinfo->port); |
1350 | } | 1384 | } |
1351 | 1385 | ||
1352 | static int __devexit cpm_uart_remove(struct of_device *ofdev) | 1386 | static int __devexit cpm_uart_remove(struct platform_device *ofdev) |
1353 | { | 1387 | { |
1354 | struct uart_cpm_port *pinfo = dev_get_drvdata(&ofdev->dev); | 1388 | struct uart_cpm_port *pinfo = dev_get_drvdata(&ofdev->dev); |
1355 | return uart_remove_one_port(&cpm_reg, &pinfo->port); | 1389 | return uart_remove_one_port(&cpm_reg, &pinfo->port); |
@@ -1372,8 +1406,11 @@ static struct of_device_id cpm_uart_match[] = { | |||
1372 | }; | 1406 | }; |
1373 | 1407 | ||
1374 | static struct of_platform_driver cpm_uart_driver = { | 1408 | static struct of_platform_driver cpm_uart_driver = { |
1375 | .name = "cpm_uart", | 1409 | .driver = { |
1376 | .match_table = cpm_uart_match, | 1410 | .name = "cpm_uart", |
1411 | .owner = THIS_MODULE, | ||
1412 | .of_match_table = cpm_uart_match, | ||
1413 | }, | ||
1377 | .probe = cpm_uart_probe, | 1414 | .probe = cpm_uart_probe, |
1378 | .remove = cpm_uart_remove, | 1415 | .remove = cpm_uart_remove, |
1379 | }; | 1416 | }; |
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c index 1b94c56ec239..3fc1d66e32c6 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c | |||
@@ -29,6 +29,7 @@ | |||
29 | 29 | ||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/tty.h> | 31 | #include <linux/tty.h> |
32 | #include <linux/gfp.h> | ||
32 | #include <linux/ioport.h> | 33 | #include <linux/ioport.h> |
33 | #include <linux/init.h> | 34 | #include <linux/init.h> |
34 | #include <linux/serial.h> | 35 | #include <linux/serial.h> |
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c index 141c0a3333ad..814ac006393f 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/tty.h> | 31 | #include <linux/tty.h> |
32 | #include <linux/ioport.h> | 32 | #include <linux/ioport.h> |
33 | #include <linux/slab.h> | ||
33 | #include <linux/init.h> | 34 | #include <linux/init.h> |
34 | #include <linux/serial.h> | 35 | #include <linux/serial.h> |
35 | #include <linux/console.h> | 36 | #include <linux/console.h> |
@@ -61,7 +62,7 @@ void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port, | |||
61 | void __iomem *pram; | 62 | void __iomem *pram; |
62 | unsigned long offset; | 63 | unsigned long offset; |
63 | struct resource res; | 64 | struct resource res; |
64 | unsigned long len; | 65 | resource_size_t len; |
65 | 66 | ||
66 | /* Don't remap parameter RAM if it has already been initialized | 67 | /* Don't remap parameter RAM if it has already been initialized |
67 | * during console setup. | 68 | * during console setup. |
@@ -74,7 +75,7 @@ void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port, | |||
74 | if (of_address_to_resource(np, 1, &res)) | 75 | if (of_address_to_resource(np, 1, &res)) |
75 | return NULL; | 76 | return NULL; |
76 | 77 | ||
77 | len = 1 + res.end - res.start; | 78 | len = resource_size(&res); |
78 | pram = ioremap(res.start, len); | 79 | pram = ioremap(res.start, len); |
79 | if (!pram) | 80 | if (!pram) |
80 | return NULL; | 81 | return NULL; |
@@ -132,7 +133,7 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) | |||
132 | memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) + | 133 | memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) + |
133 | L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize); | 134 | L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize); |
134 | if (is_con) { | 135 | if (is_con) { |
135 | mem_addr = alloc_bootmem(memsz); | 136 | mem_addr = kzalloc(memsz, GFP_NOWAIT); |
136 | dma_addr = virt_to_bus(mem_addr); | 137 | dma_addr = virt_to_bus(mem_addr); |
137 | } | 138 | } |
138 | else | 139 | else |
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c index 7be52fe288eb..bcc31f2140ac 100644 --- a/drivers/serial/crisv10.c +++ b/drivers/serial/crisv10.c | |||
@@ -1410,11 +1410,12 @@ e100_enable_rs485(struct tty_struct *tty, struct serial_rs485 *r) | |||
1410 | CONFIG_ETRAX_RS485_LTC1387_RXEN_PORT_G_BIT, 1); | 1410 | CONFIG_ETRAX_RS485_LTC1387_RXEN_PORT_G_BIT, 1); |
1411 | #endif | 1411 | #endif |
1412 | 1412 | ||
1413 | info->rs485.flags = r->flags; | 1413 | info->rs485 = *r; |
1414 | if (r->delay_rts_before_send >= 1000) | 1414 | |
1415 | /* Maximum delay before RTS equal to 1000 */ | ||
1416 | if (info->rs485.delay_rts_before_send >= 1000) | ||
1415 | info->rs485.delay_rts_before_send = 1000; | 1417 | info->rs485.delay_rts_before_send = 1000; |
1416 | else | 1418 | |
1417 | info->rs485.delay_rts_before_send = r->delay_rts_before_send; | ||
1418 | /* printk("rts: on send = %i, after = %i, enabled = %i", | 1419 | /* printk("rts: on send = %i, after = %i, enabled = %i", |
1419 | info->rs485.rts_on_send, | 1420 | info->rs485.rts_on_send, |
1420 | info->rs485.rts_after_sent, | 1421 | info->rs485.rts_after_sent, |
@@ -3233,9 +3234,9 @@ rs_write(struct tty_struct *tty, | |||
3233 | e100_disable_rx(info); | 3234 | e100_disable_rx(info); |
3234 | e100_enable_rx_irq(info); | 3235 | e100_enable_rx_irq(info); |
3235 | #endif | 3236 | #endif |
3236 | 3237 | if ((info->rs485.flags & SER_RS485_RTS_BEFORE_SEND) && | |
3237 | if (info->rs485.delay_rts_before_send > 0) | 3238 | (info->rs485.delay_rts_before_send > 0)) |
3238 | msleep(info->rs485.delay_rts_before_send); | 3239 | msleep(info->rs485.delay_rts_before_send); |
3239 | } | 3240 | } |
3240 | #endif /* CONFIG_ETRAX_RS485 */ | 3241 | #endif /* CONFIG_ETRAX_RS485 */ |
3241 | 3242 | ||
@@ -3693,6 +3694,11 @@ rs_ioctl(struct tty_struct *tty, struct file * file, | |||
3693 | 3694 | ||
3694 | rs485data.delay_rts_before_send = rs485ctrl.delay_rts_before_send; | 3695 | rs485data.delay_rts_before_send = rs485ctrl.delay_rts_before_send; |
3695 | rs485data.flags = 0; | 3696 | rs485data.flags = 0; |
3697 | if (rs485data.delay_rts_before_send != 0) | ||
3698 | rs485data.flags |= SER_RS485_RTS_BEFORE_SEND; | ||
3699 | else | ||
3700 | rs485data.flags &= ~(SER_RS485_RTS_BEFORE_SEND); | ||
3701 | |||
3696 | if (rs485ctrl.enabled) | 3702 | if (rs485ctrl.enabled) |
3697 | rs485data.flags |= SER_RS485_ENABLED; | 3703 | rs485data.flags |= SER_RS485_ENABLED; |
3698 | else | 3704 | else |
@@ -3723,6 +3729,17 @@ rs_ioctl(struct tty_struct *tty, struct file * file, | |||
3723 | return e100_enable_rs485(tty, &rs485data); | 3729 | return e100_enable_rs485(tty, &rs485data); |
3724 | } | 3730 | } |
3725 | 3731 | ||
3732 | case TIOCGRS485: | ||
3733 | { | ||
3734 | struct serial_rs485 *rs485data = | ||
3735 | &(((struct e100_serial *)tty->driver_data)->rs485); | ||
3736 | /* This is the ioctl to get RS485 data from user-space */ | ||
3737 | if (copy_to_user((struct serial_rs485 *) arg, | ||
3738 | rs485data, | ||
3739 | sizeof(struct serial_rs485))) | ||
3740 | return -EFAULT; | ||
3741 | break; | ||
3742 | } | ||
3726 | 3743 | ||
3727 | case TIOCSERWRRS485: | 3744 | case TIOCSERWRRS485: |
3728 | { | 3745 | { |
@@ -3923,7 +3940,6 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) | |||
3923 | * Check R_DMA_CHx_STATUS bit 0-6=number of available bytes in FIFO | 3940 | * Check R_DMA_CHx_STATUS bit 0-6=number of available bytes in FIFO |
3924 | * R_DMA_CHx_HWSW bit 31-16=nbr of bytes left in DMA buffer (0=64k) | 3941 | * R_DMA_CHx_HWSW bit 31-16=nbr of bytes left in DMA buffer (0=64k) |
3925 | */ | 3942 | */ |
3926 | lock_kernel(); | ||
3927 | orig_jiffies = jiffies; | 3943 | orig_jiffies = jiffies; |
3928 | while (info->xmit.head != info->xmit.tail || /* More in send queue */ | 3944 | while (info->xmit.head != info->xmit.tail || /* More in send queue */ |
3929 | (*info->ostatusadr & 0x007f) || /* more in FIFO */ | 3945 | (*info->ostatusadr & 0x007f) || /* more in FIFO */ |
@@ -3940,7 +3956,6 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) | |||
3940 | curr_time_usec - info->last_tx_active_usec; | 3956 | curr_time_usec - info->last_tx_active_usec; |
3941 | } | 3957 | } |
3942 | set_current_state(TASK_RUNNING); | 3958 | set_current_state(TASK_RUNNING); |
3943 | unlock_kernel(); | ||
3944 | } | 3959 | } |
3945 | 3960 | ||
3946 | /* | 3961 | /* |
@@ -3980,7 +3995,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, | |||
3980 | */ | 3995 | */ |
3981 | if (tty_hung_up_p(filp) || | 3996 | if (tty_hung_up_p(filp) || |
3982 | (info->flags & ASYNC_CLOSING)) { | 3997 | (info->flags & ASYNC_CLOSING)) { |
3983 | wait_event_interruptible(info->close_wait, | 3998 | wait_event_interruptible_tty(info->close_wait, |
3984 | !(info->flags & ASYNC_CLOSING)); | 3999 | !(info->flags & ASYNC_CLOSING)); |
3985 | #ifdef SERIAL_DO_RESTART | 4000 | #ifdef SERIAL_DO_RESTART |
3986 | if (info->flags & ASYNC_HUP_NOTIFY) | 4001 | if (info->flags & ASYNC_HUP_NOTIFY) |
@@ -4056,7 +4071,9 @@ block_til_ready(struct tty_struct *tty, struct file * filp, | |||
4056 | printk("block_til_ready blocking: ttyS%d, count = %d\n", | 4071 | printk("block_til_ready blocking: ttyS%d, count = %d\n", |
4057 | info->line, info->count); | 4072 | info->line, info->count); |
4058 | #endif | 4073 | #endif |
4074 | tty_unlock(); | ||
4059 | schedule(); | 4075 | schedule(); |
4076 | tty_lock(); | ||
4060 | } | 4077 | } |
4061 | set_current_state(TASK_RUNNING); | 4078 | set_current_state(TASK_RUNNING); |
4062 | remove_wait_queue(&info->open_wait, &wait); | 4079 | remove_wait_queue(&info->open_wait, &wait); |
@@ -4138,7 +4155,7 @@ rs_open(struct tty_struct *tty, struct file * filp) | |||
4138 | */ | 4155 | */ |
4139 | if (tty_hung_up_p(filp) || | 4156 | if (tty_hung_up_p(filp) || |
4140 | (info->flags & ASYNC_CLOSING)) { | 4157 | (info->flags & ASYNC_CLOSING)) { |
4141 | wait_event_interruptible(info->close_wait, | 4158 | wait_event_interruptible_tty(info->close_wait, |
4142 | !(info->flags & ASYNC_CLOSING)); | 4159 | !(info->flags & ASYNC_CLOSING)); |
4143 | #ifdef SERIAL_DO_RESTART | 4160 | #ifdef SERIAL_DO_RESTART |
4144 | return ((info->flags & ASYNC_HUP_NOTIFY) ? | 4161 | return ((info->flags & ASYNC_HUP_NOTIFY) ? |
@@ -4515,14 +4532,15 @@ static int __init rs_init(void) | |||
4515 | /* Set sane defaults */ | 4532 | /* Set sane defaults */ |
4516 | info->rs485.flags &= ~(SER_RS485_RTS_ON_SEND); | 4533 | info->rs485.flags &= ~(SER_RS485_RTS_ON_SEND); |
4517 | info->rs485.flags |= SER_RS485_RTS_AFTER_SEND; | 4534 | info->rs485.flags |= SER_RS485_RTS_AFTER_SEND; |
4535 | info->rs485.flags &= ~(SER_RS485_RTS_BEFORE_SEND); | ||
4518 | info->rs485.delay_rts_before_send = 0; | 4536 | info->rs485.delay_rts_before_send = 0; |
4519 | info->rs485.flags &= ~(SER_RS485_ENABLED); | 4537 | info->rs485.flags &= ~(SER_RS485_ENABLED); |
4520 | #endif | 4538 | #endif |
4521 | INIT_WORK(&info->work, do_softint); | 4539 | INIT_WORK(&info->work, do_softint); |
4522 | 4540 | ||
4523 | if (info->enabled) { | 4541 | if (info->enabled) { |
4524 | printk(KERN_INFO "%s%d at 0x%x is a builtin UART with DMA\n", | 4542 | printk(KERN_INFO "%s%d at %p is a builtin UART with DMA\n", |
4525 | serial_driver->name, info->line, (unsigned int)info->ioport); | 4543 | serial_driver->name, info->line, info->ioport); |
4526 | } | 4544 | } |
4527 | } | 4545 | } |
4528 | #ifdef CONFIG_ETRAX_FAST_TIMER | 4546 | #ifdef CONFIG_ETRAX_FAST_TIMER |
diff --git a/drivers/serial/dz.c b/drivers/serial/dz.c index 6042b87797a1..57421d776329 100644 --- a/drivers/serial/dz.c +++ b/drivers/serial/dz.c | |||
@@ -197,7 +197,7 @@ static inline void dz_receive_chars(struct dz_mux *mux) | |||
197 | while ((status = dz_in(dport, DZ_RBUF)) & DZ_DVAL) { | 197 | while ((status = dz_in(dport, DZ_RBUF)) & DZ_DVAL) { |
198 | dport = &mux->dport[LINE(status)]; | 198 | dport = &mux->dport[LINE(status)]; |
199 | uport = &dport->port; | 199 | uport = &dport->port; |
200 | tty = uport->info->port.tty; /* point to the proper dev */ | 200 | tty = uport->state->port.tty; /* point to the proper dev */ |
201 | 201 | ||
202 | ch = UCHAR(status); /* grab the char */ | 202 | ch = UCHAR(status); /* grab the char */ |
203 | flag = TTY_NORMAL; | 203 | flag = TTY_NORMAL; |
@@ -249,7 +249,7 @@ static inline void dz_receive_chars(struct dz_mux *mux) | |||
249 | } | 249 | } |
250 | for (i = 0; i < DZ_NB_PORT; i++) | 250 | for (i = 0; i < DZ_NB_PORT; i++) |
251 | if (lines_rx[i]) | 251 | if (lines_rx[i]) |
252 | tty_flip_buffer_push(mux->dport[i].port.info->port.tty); | 252 | tty_flip_buffer_push(mux->dport[i].port.state->port.tty); |
253 | } | 253 | } |
254 | 254 | ||
255 | /* | 255 | /* |
@@ -268,7 +268,7 @@ static inline void dz_transmit_chars(struct dz_mux *mux) | |||
268 | 268 | ||
269 | status = dz_in(dport, DZ_CSR); | 269 | status = dz_in(dport, DZ_CSR); |
270 | dport = &mux->dport[LINE(status)]; | 270 | dport = &mux->dport[LINE(status)]; |
271 | xmit = &dport->port.info->xmit; | 271 | xmit = &dport->port.state->xmit; |
272 | 272 | ||
273 | if (dport->port.x_char) { /* XON/XOFF chars */ | 273 | if (dport->port.x_char) { /* XON/XOFF chars */ |
274 | dz_out(dport, DZ_TDR, dport->port.x_char); | 274 | dz_out(dport, DZ_TDR, dport->port.x_char); |
diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c index 9f2891c2c4a2..53a468227056 100644 --- a/drivers/serial/icom.c +++ b/drivers/serial/icom.c | |||
@@ -307,7 +307,7 @@ static void stop_processor(struct icom_port *icom_port) | |||
307 | if (port < 4) { | 307 | if (port < 4) { |
308 | temp = readl(stop_proc[port].global_control_reg); | 308 | temp = readl(stop_proc[port].global_control_reg); |
309 | temp = | 309 | temp = |
310 | (temp & ~start_proc[port].processor_id) | stop_proc[port].processor_id; | 310 | (temp & ~start_proc[port].processor_id) | stop_proc[port].processor_id; |
311 | writel(temp, stop_proc[port].global_control_reg); | 311 | writel(temp, stop_proc[port].global_control_reg); |
312 | 312 | ||
313 | /* write flush */ | 313 | /* write flush */ |
@@ -336,7 +336,7 @@ static void start_processor(struct icom_port *icom_port) | |||
336 | if (port < 4) { | 336 | if (port < 4) { |
337 | temp = readl(start_proc[port].global_control_reg); | 337 | temp = readl(start_proc[port].global_control_reg); |
338 | temp = | 338 | temp = |
339 | (temp & ~stop_proc[port].processor_id) | start_proc[port].processor_id; | 339 | (temp & ~stop_proc[port].processor_id) | start_proc[port].processor_id; |
340 | writel(temp, start_proc[port].global_control_reg); | 340 | writel(temp, start_proc[port].global_control_reg); |
341 | 341 | ||
342 | /* write flush */ | 342 | /* write flush */ |
@@ -509,8 +509,8 @@ static void load_code(struct icom_port *icom_port) | |||
509 | dev_err(&icom_port->adapter->pci_dev->dev,"Port not opertional\n"); | 509 | dev_err(&icom_port->adapter->pci_dev->dev,"Port not opertional\n"); |
510 | } | 510 | } |
511 | 511 | ||
512 | if (new_page != NULL) | 512 | if (new_page != NULL) |
513 | pci_free_consistent(dev, 4096, new_page, temp_pci); | 513 | pci_free_consistent(dev, 4096, new_page, temp_pci); |
514 | } | 514 | } |
515 | 515 | ||
516 | static int startup(struct icom_port *icom_port) | 516 | static int startup(struct icom_port *icom_port) |
@@ -617,7 +617,7 @@ static void shutdown(struct icom_port *icom_port) | |||
617 | * disable break condition | 617 | * disable break condition |
618 | */ | 618 | */ |
619 | cmdReg = readb(&icom_port->dram->CmdReg); | 619 | cmdReg = readb(&icom_port->dram->CmdReg); |
620 | if ((cmdReg | CMD_SND_BREAK) == CMD_SND_BREAK) { | 620 | if (cmdReg & CMD_SND_BREAK) { |
621 | writeb(cmdReg & ~CMD_SND_BREAK, &icom_port->dram->CmdReg); | 621 | writeb(cmdReg & ~CMD_SND_BREAK, &icom_port->dram->CmdReg); |
622 | } | 622 | } |
623 | } | 623 | } |
@@ -627,7 +627,7 @@ static int icom_write(struct uart_port *port) | |||
627 | unsigned long data_count; | 627 | unsigned long data_count; |
628 | unsigned char cmdReg; | 628 | unsigned char cmdReg; |
629 | unsigned long offset; | 629 | unsigned long offset; |
630 | int temp_tail = port->info->xmit.tail; | 630 | int temp_tail = port->state->xmit.tail; |
631 | 631 | ||
632 | trace(ICOM_PORT, "WRITE", 0); | 632 | trace(ICOM_PORT, "WRITE", 0); |
633 | 633 | ||
@@ -638,11 +638,11 @@ static int icom_write(struct uart_port *port) | |||
638 | } | 638 | } |
639 | 639 | ||
640 | data_count = 0; | 640 | data_count = 0; |
641 | while ((port->info->xmit.head != temp_tail) && | 641 | while ((port->state->xmit.head != temp_tail) && |
642 | (data_count <= XMIT_BUFF_SZ)) { | 642 | (data_count <= XMIT_BUFF_SZ)) { |
643 | 643 | ||
644 | ICOM_PORT->xmit_buf[data_count++] = | 644 | ICOM_PORT->xmit_buf[data_count++] = |
645 | port->info->xmit.buf[temp_tail]; | 645 | port->state->xmit.buf[temp_tail]; |
646 | 646 | ||
647 | temp_tail++; | 647 | temp_tail++; |
648 | temp_tail &= (UART_XMIT_SIZE - 1); | 648 | temp_tail &= (UART_XMIT_SIZE - 1); |
@@ -694,8 +694,8 @@ static inline void check_modem_status(struct icom_port *icom_port) | |||
694 | uart_handle_cts_change(&icom_port->uart_port, | 694 | uart_handle_cts_change(&icom_port->uart_port, |
695 | delta_status & ICOM_CTS); | 695 | delta_status & ICOM_CTS); |
696 | 696 | ||
697 | wake_up_interruptible(&icom_port->uart_port.info-> | 697 | wake_up_interruptible(&icom_port->uart_port.state-> |
698 | delta_msr_wait); | 698 | port.delta_msr_wait); |
699 | old_status = status; | 699 | old_status = status; |
700 | } | 700 | } |
701 | spin_unlock(&icom_port->uart_port.lock); | 701 | spin_unlock(&icom_port->uart_port.lock); |
@@ -718,10 +718,10 @@ static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port) | |||
718 | icom_port->uart_port.icount.tx += count; | 718 | icom_port->uart_port.icount.tx += count; |
719 | 719 | ||
720 | for (i=0; i<count && | 720 | for (i=0; i<count && |
721 | !uart_circ_empty(&icom_port->uart_port.info->xmit); i++) { | 721 | !uart_circ_empty(&icom_port->uart_port.state->xmit); i++) { |
722 | 722 | ||
723 | icom_port->uart_port.info->xmit.tail++; | 723 | icom_port->uart_port.state->xmit.tail++; |
724 | icom_port->uart_port.info->xmit.tail &= | 724 | icom_port->uart_port.state->xmit.tail &= |
725 | (UART_XMIT_SIZE - 1); | 725 | (UART_XMIT_SIZE - 1); |
726 | } | 726 | } |
727 | 727 | ||
@@ -735,7 +735,7 @@ static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port) | |||
735 | static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port) | 735 | static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port) |
736 | { | 736 | { |
737 | short int count, rcv_buff; | 737 | short int count, rcv_buff; |
738 | struct tty_struct *tty = icom_port->uart_port.info->port.tty; | 738 | struct tty_struct *tty = icom_port->uart_port.state->port.tty; |
739 | unsigned short int status; | 739 | unsigned short int status; |
740 | struct uart_icount *icount; | 740 | struct uart_icount *icount; |
741 | unsigned long offset; | 741 | unsigned long offset; |
@@ -751,7 +751,6 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port) | |||
751 | trace(icom_port, "FID_STATUS", status); | 751 | trace(icom_port, "FID_STATUS", status); |
752 | count = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].leLength); | 752 | count = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].leLength); |
753 | 753 | ||
754 | count = tty_buffer_request_room(tty, count); | ||
755 | trace(icom_port, "RCV_COUNT", count); | 754 | trace(icom_port, "RCV_COUNT", count); |
756 | 755 | ||
757 | trace(icom_port, "REAL_COUNT", count); | 756 | trace(icom_port, "REAL_COUNT", count); |
@@ -1493,15 +1492,15 @@ static int __devinit icom_probe(struct pci_dev *dev, | |||
1493 | const struct pci_device_id *ent) | 1492 | const struct pci_device_id *ent) |
1494 | { | 1493 | { |
1495 | int index; | 1494 | int index; |
1496 | unsigned int command_reg; | 1495 | unsigned int command_reg; |
1497 | int retval; | 1496 | int retval; |
1498 | struct icom_adapter *icom_adapter; | 1497 | struct icom_adapter *icom_adapter; |
1499 | struct icom_port *icom_port; | 1498 | struct icom_port *icom_port; |
1500 | 1499 | ||
1501 | retval = pci_enable_device(dev); | 1500 | retval = pci_enable_device(dev); |
1502 | if (retval) { | 1501 | if (retval) { |
1503 | dev_err(&dev->dev, "Device enable FAILED\n"); | 1502 | dev_err(&dev->dev, "Device enable FAILED\n"); |
1504 | return retval; | 1503 | return retval; |
1505 | } | 1504 | } |
1506 | 1505 | ||
1507 | if ( (retval = pci_request_regions(dev, "icom"))) { | 1506 | if ( (retval = pci_request_regions(dev, "icom"))) { |
@@ -1510,23 +1509,23 @@ static int __devinit icom_probe(struct pci_dev *dev, | |||
1510 | return retval; | 1509 | return retval; |
1511 | } | 1510 | } |
1512 | 1511 | ||
1513 | pci_set_master(dev); | 1512 | pci_set_master(dev); |
1514 | 1513 | ||
1515 | if ( (retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg))) { | 1514 | if ( (retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg))) { |
1516 | dev_err(&dev->dev, "PCI Config read FAILED\n"); | 1515 | dev_err(&dev->dev, "PCI Config read FAILED\n"); |
1517 | return retval; | 1516 | return retval; |
1518 | } | 1517 | } |
1519 | 1518 | ||
1520 | pci_write_config_dword(dev, PCI_COMMAND, | 1519 | pci_write_config_dword(dev, PCI_COMMAND, |
1521 | command_reg | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | 1520 | command_reg | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
1522 | | PCI_COMMAND_PARITY | PCI_COMMAND_SERR); | 1521 | | PCI_COMMAND_PARITY | PCI_COMMAND_SERR); |
1523 | 1522 | ||
1524 | if (ent->driver_data == ADAPTER_V1) { | 1523 | if (ent->driver_data == ADAPTER_V1) { |
1525 | pci_write_config_dword(dev, 0x44, 0x8300830A); | 1524 | pci_write_config_dword(dev, 0x44, 0x8300830A); |
1526 | } else { | 1525 | } else { |
1527 | pci_write_config_dword(dev, 0x44, 0x42004200); | 1526 | pci_write_config_dword(dev, 0x44, 0x42004200); |
1528 | pci_write_config_dword(dev, 0x48, 0x42004200); | 1527 | pci_write_config_dword(dev, 0x48, 0x42004200); |
1529 | } | 1528 | } |
1530 | 1529 | ||
1531 | 1530 | ||
1532 | retval = icom_alloc_adapter(&icom_adapter); | 1531 | retval = icom_alloc_adapter(&icom_adapter); |
@@ -1536,10 +1535,10 @@ static int __devinit icom_probe(struct pci_dev *dev, | |||
1536 | goto probe_exit0; | 1535 | goto probe_exit0; |
1537 | } | 1536 | } |
1538 | 1537 | ||
1539 | icom_adapter->base_addr_pci = pci_resource_start(dev, 0); | 1538 | icom_adapter->base_addr_pci = pci_resource_start(dev, 0); |
1540 | icom_adapter->pci_dev = dev; | 1539 | icom_adapter->pci_dev = dev; |
1541 | icom_adapter->version = ent->driver_data; | 1540 | icom_adapter->version = ent->driver_data; |
1542 | icom_adapter->subsystem_id = ent->subdevice; | 1541 | icom_adapter->subsystem_id = ent->subdevice; |
1543 | 1542 | ||
1544 | 1543 | ||
1545 | retval = icom_init_ports(icom_adapter); | 1544 | retval = icom_init_ports(icom_adapter); |
@@ -1548,8 +1547,7 @@ static int __devinit icom_probe(struct pci_dev *dev, | |||
1548 | goto probe_exit1; | 1547 | goto probe_exit1; |
1549 | } | 1548 | } |
1550 | 1549 | ||
1551 | icom_adapter->base_addr = ioremap(icom_adapter->base_addr_pci, | 1550 | icom_adapter->base_addr = pci_ioremap_bar(dev, 0); |
1552 | pci_resource_len(dev, 0)); | ||
1553 | 1551 | ||
1554 | if (!icom_adapter->base_addr) | 1552 | if (!icom_adapter->base_addr) |
1555 | goto probe_exit1; | 1553 | goto probe_exit1; |
@@ -1563,7 +1561,7 @@ static int __devinit icom_probe(struct pci_dev *dev, | |||
1563 | 1561 | ||
1564 | retval = icom_load_ports(icom_adapter); | 1562 | retval = icom_load_ports(icom_adapter); |
1565 | 1563 | ||
1566 | for (index = 0; index < icom_adapter->numb_ports; index++) { | 1564 | for (index = 0; index < icom_adapter->numb_ports; index++) { |
1567 | icom_port = &icom_adapter->port_info[index]; | 1565 | icom_port = &icom_adapter->port_info[index]; |
1568 | 1566 | ||
1569 | if (icom_port->status == ICOM_PORT_ACTIVE) { | 1567 | if (icom_port->status == ICOM_PORT_ACTIVE) { |
@@ -1580,7 +1578,7 @@ static int __devinit icom_probe(struct pci_dev *dev, | |||
1580 | icom_port->status = ICOM_PORT_OFF; | 1578 | icom_port->status = ICOM_PORT_OFF; |
1581 | dev_err(&dev->dev, "Device add failed\n"); | 1579 | dev_err(&dev->dev, "Device add failed\n"); |
1582 | } else | 1580 | } else |
1583 | dev_info(&dev->dev, "Device added\n"); | 1581 | dev_info(&dev->dev, "Device added\n"); |
1584 | } | 1582 | } |
1585 | } | 1583 | } |
1586 | 1584 | ||
@@ -1596,9 +1594,7 @@ probe_exit0: | |||
1596 | pci_release_regions(dev); | 1594 | pci_release_regions(dev); |
1597 | pci_disable_device(dev); | 1595 | pci_disable_device(dev); |
1598 | 1596 | ||
1599 | return retval; | 1597 | return retval; |
1600 | |||
1601 | |||
1602 | } | 1598 | } |
1603 | 1599 | ||
1604 | static void __devexit icom_remove(struct pci_dev *dev) | 1600 | static void __devexit icom_remove(struct pci_dev *dev) |
@@ -1657,4 +1653,6 @@ MODULE_DESCRIPTION("IBM iSeries Serial IOA driver"); | |||
1657 | MODULE_SUPPORTED_DEVICE | 1653 | MODULE_SUPPORTED_DEVICE |
1658 | ("IBM iSeries 2745, 2771, 2772, 2742, 2793 and 2805 Communications adapters"); | 1654 | ("IBM iSeries 2745, 2771, 2772, 2742, 2793 and 2805 Communications adapters"); |
1659 | MODULE_LICENSE("GPL"); | 1655 | MODULE_LICENSE("GPL"); |
1660 | 1656 | MODULE_FIRMWARE("icom_call_setup.bin"); | |
1657 | MODULE_FIRMWARE("icom_res_dce.bin"); | ||
1658 | MODULE_FIRMWARE("icom_asc.bin"); | ||
diff --git a/drivers/serial/ifx6x60.c b/drivers/serial/ifx6x60.c new file mode 100644 index 000000000000..ab93763862d5 --- /dev/null +++ b/drivers/serial/ifx6x60.c | |||
@@ -0,0 +1,1406 @@ | |||
1 | /**************************************************************************** | ||
2 | * | ||
3 | * Driver for the IFX 6x60 spi modem. | ||
4 | * | ||
5 | * Copyright (C) 2008 Option International | ||
6 | * Copyright (C) 2008 Filip Aben <f.aben@option.com> | ||
7 | * Denis Joseph Barrow <d.barow@option.com> | ||
8 | * Jan Dumon <j.dumon@option.com> | ||
9 | * | ||
10 | * Copyright (C) 2009, 2010 Intel Corp | ||
11 | * Russ Gorby <richardx.r.gorby@intel.com> | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License version 2 as | ||
15 | * published by the Free Software Foundation. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, | ||
25 | * USA | ||
26 | * | ||
27 | * Driver modified by Intel from Option gtm501l_spi.c | ||
28 | * | ||
29 | * Notes | ||
30 | * o The driver currently assumes a single device only. If you need to | ||
31 | * change this then look for saved_ifx_dev and add a device lookup | ||
32 | * o The driver is intended to be big-endian safe but has never been | ||
33 | * tested that way (no suitable hardware). There are a couple of FIXME | ||
34 | * notes by areas that may need addressing | ||
35 | * o Some of the GPIO naming/setup assumptions may need revisiting if | ||
36 | * you need to use this driver for another platform. | ||
37 | * | ||
38 | *****************************************************************************/ | ||
39 | #include <linux/module.h> | ||
40 | #include <linux/termios.h> | ||
41 | #include <linux/tty.h> | ||
42 | #include <linux/device.h> | ||
43 | #include <linux/spi/spi.h> | ||
44 | #include <linux/tty.h> | ||
45 | #include <linux/kfifo.h> | ||
46 | #include <linux/tty_flip.h> | ||
47 | #include <linux/timer.h> | ||
48 | #include <linux/serial.h> | ||
49 | #include <linux/interrupt.h> | ||
50 | #include <linux/irq.h> | ||
51 | #include <linux/rfkill.h> | ||
52 | #include <linux/fs.h> | ||
53 | #include <linux/ip.h> | ||
54 | #include <linux/dmapool.h> | ||
55 | #include <linux/gpio.h> | ||
56 | #include <linux/sched.h> | ||
57 | #include <linux/time.h> | ||
58 | #include <linux/wait.h> | ||
59 | #include <linux/tty.h> | ||
60 | #include <linux/pm.h> | ||
61 | #include <linux/pm_runtime.h> | ||
62 | #include <linux/spi/ifx_modem.h> | ||
63 | #include <linux/delay.h> | ||
64 | |||
65 | #include "ifx6x60.h" | ||
66 | |||
67 | #define IFX_SPI_MORE_MASK 0x10 | ||
68 | #define IFX_SPI_MORE_BIT 12 /* bit position in u16 */ | ||
69 | #define IFX_SPI_CTS_BIT 13 /* bit position in u16 */ | ||
70 | #define IFX_SPI_TTY_ID 0 | ||
71 | #define IFX_SPI_TIMEOUT_SEC 2 | ||
72 | #define IFX_SPI_HEADER_0 (-1) | ||
73 | #define IFX_SPI_HEADER_F (-2) | ||
74 | |||
75 | /* forward reference */ | ||
76 | static void ifx_spi_handle_srdy(struct ifx_spi_device *ifx_dev); | ||
77 | |||
78 | /* local variables */ | ||
79 | static int spi_b16 = 1; /* 8 or 16 bit word length */ | ||
80 | static struct tty_driver *tty_drv; | ||
81 | static struct ifx_spi_device *saved_ifx_dev; | ||
82 | static struct lock_class_key ifx_spi_key; | ||
83 | |||
84 | /* GPIO/GPE settings */ | ||
85 | |||
86 | /** | ||
87 | * mrdy_set_high - set MRDY GPIO | ||
88 | * @ifx: device we are controlling | ||
89 | * | ||
90 | */ | ||
91 | static inline void mrdy_set_high(struct ifx_spi_device *ifx) | ||
92 | { | ||
93 | gpio_set_value(ifx->gpio.mrdy, 1); | ||
94 | } | ||
95 | |||
96 | /** | ||
97 | * mrdy_set_low - clear MRDY GPIO | ||
98 | * @ifx: device we are controlling | ||
99 | * | ||
100 | */ | ||
101 | static inline void mrdy_set_low(struct ifx_spi_device *ifx) | ||
102 | { | ||
103 | gpio_set_value(ifx->gpio.mrdy, 0); | ||
104 | } | ||
105 | |||
106 | /** | ||
107 | * ifx_spi_power_state_set | ||
108 | * @ifx_dev: our SPI device | ||
109 | * @val: bits to set | ||
110 | * | ||
111 | * Set bit in power status and signal power system if status becomes non-0 | ||
112 | */ | ||
113 | static void | ||
114 | ifx_spi_power_state_set(struct ifx_spi_device *ifx_dev, unsigned char val) | ||
115 | { | ||
116 | unsigned long flags; | ||
117 | |||
118 | spin_lock_irqsave(&ifx_dev->power_lock, flags); | ||
119 | |||
120 | /* | ||
121 | * if power status is already non-0, just update, else | ||
122 | * tell power system | ||
123 | */ | ||
124 | if (!ifx_dev->power_status) | ||
125 | pm_runtime_get(&ifx_dev->spi_dev->dev); | ||
126 | ifx_dev->power_status |= val; | ||
127 | |||
128 | spin_unlock_irqrestore(&ifx_dev->power_lock, flags); | ||
129 | } | ||
130 | |||
131 | /** | ||
132 | * ifx_spi_power_state_clear - clear power bit | ||
133 | * @ifx_dev: our SPI device | ||
134 | * @val: bits to clear | ||
135 | * | ||
136 | * clear bit in power status and signal power system if status becomes 0 | ||
137 | */ | ||
138 | static void | ||
139 | ifx_spi_power_state_clear(struct ifx_spi_device *ifx_dev, unsigned char val) | ||
140 | { | ||
141 | unsigned long flags; | ||
142 | |||
143 | spin_lock_irqsave(&ifx_dev->power_lock, flags); | ||
144 | |||
145 | if (ifx_dev->power_status) { | ||
146 | ifx_dev->power_status &= ~val; | ||
147 | if (!ifx_dev->power_status) | ||
148 | pm_runtime_put(&ifx_dev->spi_dev->dev); | ||
149 | } | ||
150 | |||
151 | spin_unlock_irqrestore(&ifx_dev->power_lock, flags); | ||
152 | } | ||
153 | |||
154 | /** | ||
155 | * swap_buf | ||
156 | * @buf: our buffer | ||
157 | * @len : number of bytes (not words) in the buffer | ||
158 | * @end: end of buffer | ||
159 | * | ||
160 | * Swap the contents of a buffer into big endian format | ||
161 | */ | ||
162 | static inline void swap_buf(u16 *buf, int len, void *end) | ||
163 | { | ||
164 | int n; | ||
165 | |||
166 | len = ((len + 1) >> 1); | ||
167 | if ((void *)&buf[len] > end) { | ||
168 | pr_err("swap_buf: swap exceeds boundary (%p > %p)!", | ||
169 | &buf[len], end); | ||
170 | return; | ||
171 | } | ||
172 | for (n = 0; n < len; n++) { | ||
173 | *buf = cpu_to_be16(*buf); | ||
174 | buf++; | ||
175 | } | ||
176 | } | ||
177 | |||
178 | /** | ||
179 | * mrdy_assert - assert MRDY line | ||
180 | * @ifx_dev: our SPI device | ||
181 | * | ||
182 | * Assert mrdy and set timer to wait for SRDY interrupt, if SRDY is low | ||
183 | * now. | ||
184 | * | ||
185 | * FIXME: Can SRDY even go high as we are running this code ? | ||
186 | */ | ||
187 | static void mrdy_assert(struct ifx_spi_device *ifx_dev) | ||
188 | { | ||
189 | int val = gpio_get_value(ifx_dev->gpio.srdy); | ||
190 | if (!val) { | ||
191 | if (!test_and_set_bit(IFX_SPI_STATE_TIMER_PENDING, | ||
192 | &ifx_dev->flags)) { | ||
193 | ifx_dev->spi_timer.expires = | ||
194 | jiffies + IFX_SPI_TIMEOUT_SEC*HZ; | ||
195 | add_timer(&ifx_dev->spi_timer); | ||
196 | |||
197 | } | ||
198 | } | ||
199 | ifx_spi_power_state_set(ifx_dev, IFX_SPI_POWER_DATA_PENDING); | ||
200 | mrdy_set_high(ifx_dev); | ||
201 | } | ||
202 | |||
203 | /** | ||
204 | * ifx_spi_hangup - hang up an IFX device | ||
205 | * @ifx_dev: our SPI device | ||
206 | * | ||
207 | * Hang up the tty attached to the IFX device if one is currently | ||
208 | * open. If not take no action | ||
209 | */ | ||
210 | static void ifx_spi_ttyhangup(struct ifx_spi_device *ifx_dev) | ||
211 | { | ||
212 | struct tty_port *pport = &ifx_dev->tty_port; | ||
213 | struct tty_struct *tty = tty_port_tty_get(pport); | ||
214 | if (tty) { | ||
215 | tty_hangup(tty); | ||
216 | tty_kref_put(tty); | ||
217 | } | ||
218 | } | ||
219 | |||
220 | /** | ||
221 | * ifx_spi_timeout - SPI timeout | ||
222 | * @arg: our SPI device | ||
223 | * | ||
224 | * The SPI has timed out: hang up the tty. Users will then see a hangup | ||
225 | * and error events. | ||
226 | */ | ||
227 | static void ifx_spi_timeout(unsigned long arg) | ||
228 | { | ||
229 | struct ifx_spi_device *ifx_dev = (struct ifx_spi_device *)arg; | ||
230 | |||
231 | dev_warn(&ifx_dev->spi_dev->dev, "*** SPI Timeout ***"); | ||
232 | ifx_spi_ttyhangup(ifx_dev); | ||
233 | mrdy_set_low(ifx_dev); | ||
234 | clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags); | ||
235 | } | ||
236 | |||
237 | /* char/tty operations */ | ||
238 | |||
239 | /** | ||
240 | * ifx_spi_tiocmget - get modem lines | ||
241 | * @tty: our tty device | ||
242 | * @filp: file handle issuing the request | ||
243 | * | ||
244 | * Map the signal state into Linux modem flags and report the value | ||
245 | * in Linux terms | ||
246 | */ | ||
247 | static int ifx_spi_tiocmget(struct tty_struct *tty, struct file *filp) | ||
248 | { | ||
249 | unsigned int value; | ||
250 | struct ifx_spi_device *ifx_dev = tty->driver_data; | ||
251 | |||
252 | value = | ||
253 | (test_bit(IFX_SPI_RTS, &ifx_dev->signal_state) ? TIOCM_RTS : 0) | | ||
254 | (test_bit(IFX_SPI_DTR, &ifx_dev->signal_state) ? TIOCM_DTR : 0) | | ||
255 | (test_bit(IFX_SPI_CTS, &ifx_dev->signal_state) ? TIOCM_CTS : 0) | | ||
256 | (test_bit(IFX_SPI_DSR, &ifx_dev->signal_state) ? TIOCM_DSR : 0) | | ||
257 | (test_bit(IFX_SPI_DCD, &ifx_dev->signal_state) ? TIOCM_CAR : 0) | | ||
258 | (test_bit(IFX_SPI_RI, &ifx_dev->signal_state) ? TIOCM_RNG : 0); | ||
259 | return value; | ||
260 | } | ||
261 | |||
262 | /** | ||
263 | * ifx_spi_tiocmset - set modem bits | ||
264 | * @tty: the tty structure | ||
265 | * @filp: file handle issuing the request | ||
266 | * @set: bits to set | ||
267 | * @clear: bits to clear | ||
268 | * | ||
269 | * The IFX6x60 only supports DTR and RTS. Set them accordingly | ||
270 | * and flag that an update to the modem is needed. | ||
271 | * | ||
272 | * FIXME: do we need to kick the tranfers when we do this ? | ||
273 | */ | ||
274 | static int ifx_spi_tiocmset(struct tty_struct *tty, struct file *filp, | ||
275 | unsigned int set, unsigned int clear) | ||
276 | { | ||
277 | struct ifx_spi_device *ifx_dev = tty->driver_data; | ||
278 | |||
279 | if (set & TIOCM_RTS) | ||
280 | set_bit(IFX_SPI_RTS, &ifx_dev->signal_state); | ||
281 | if (set & TIOCM_DTR) | ||
282 | set_bit(IFX_SPI_DTR, &ifx_dev->signal_state); | ||
283 | if (clear & TIOCM_RTS) | ||
284 | clear_bit(IFX_SPI_RTS, &ifx_dev->signal_state); | ||
285 | if (clear & TIOCM_DTR) | ||
286 | clear_bit(IFX_SPI_DTR, &ifx_dev->signal_state); | ||
287 | |||
288 | set_bit(IFX_SPI_UPDATE, &ifx_dev->signal_state); | ||
289 | return 0; | ||
290 | } | ||
291 | |||
292 | /** | ||
293 | * ifx_spi_open - called on tty open | ||
294 | * @tty: our tty device | ||
295 | * @filp: file handle being associated with the tty | ||
296 | * | ||
297 | * Open the tty interface. We let the tty_port layer do all the work | ||
298 | * for us. | ||
299 | * | ||
300 | * FIXME: Remove single device assumption and saved_ifx_dev | ||
301 | */ | ||
302 | static int ifx_spi_open(struct tty_struct *tty, struct file *filp) | ||
303 | { | ||
304 | return tty_port_open(&saved_ifx_dev->tty_port, tty, filp); | ||
305 | } | ||
306 | |||
307 | /** | ||
308 | * ifx_spi_close - called when our tty closes | ||
309 | * @tty: the tty being closed | ||
310 | * @filp: the file handle being closed | ||
311 | * | ||
312 | * Perform the close of the tty. We use the tty_port layer to do all | ||
313 | * our hard work. | ||
314 | */ | ||
315 | static void ifx_spi_close(struct tty_struct *tty, struct file *filp) | ||
316 | { | ||
317 | struct ifx_spi_device *ifx_dev = tty->driver_data; | ||
318 | tty_port_close(&ifx_dev->tty_port, tty, filp); | ||
319 | /* FIXME: should we do an ifx_spi_reset here ? */ | ||
320 | } | ||
321 | |||
322 | /** | ||
323 | * ifx_decode_spi_header - decode received header | ||
324 | * @buffer: the received data | ||
325 | * @length: decoded length | ||
326 | * @more: decoded more flag | ||
327 | * @received_cts: status of cts we received | ||
328 | * | ||
329 | * Note how received_cts is handled -- if header is all F it is left | ||
330 | * the same as it was, if header is all 0 it is set to 0 otherwise it is | ||
331 | * taken from the incoming header. | ||
332 | * | ||
333 | * FIXME: endianness | ||
334 | */ | ||
335 | static int ifx_spi_decode_spi_header(unsigned char *buffer, int *length, | ||
336 | unsigned char *more, unsigned char *received_cts) | ||
337 | { | ||
338 | u16 h1; | ||
339 | u16 h2; | ||
340 | u16 *in_buffer = (u16 *)buffer; | ||
341 | |||
342 | h1 = *in_buffer; | ||
343 | h2 = *(in_buffer+1); | ||
344 | |||
345 | if (h1 == 0 && h2 == 0) { | ||
346 | *received_cts = 0; | ||
347 | return IFX_SPI_HEADER_0; | ||
348 | } else if (h1 == 0xffff && h2 == 0xffff) { | ||
349 | /* spi_slave_cts remains as it was */ | ||
350 | return IFX_SPI_HEADER_F; | ||
351 | } | ||
352 | |||
353 | *length = h1 & 0xfff; /* upper bits of byte are flags */ | ||
354 | *more = (buffer[1] >> IFX_SPI_MORE_BIT) & 1; | ||
355 | *received_cts = (buffer[3] >> IFX_SPI_CTS_BIT) & 1; | ||
356 | return 0; | ||
357 | } | ||
358 | |||
359 | /** | ||
360 | * ifx_setup_spi_header - set header fields | ||
361 | * @txbuffer: pointer to start of SPI buffer | ||
362 | * @tx_count: bytes | ||
363 | * @more: indicate if more to follow | ||
364 | * | ||
365 | * Format up an SPI header for a transfer | ||
366 | * | ||
367 | * FIXME: endianness? | ||
368 | */ | ||
369 | static void ifx_spi_setup_spi_header(unsigned char *txbuffer, int tx_count, | ||
370 | unsigned char more) | ||
371 | { | ||
372 | *(u16 *)(txbuffer) = tx_count; | ||
373 | *(u16 *)(txbuffer+2) = IFX_SPI_PAYLOAD_SIZE; | ||
374 | txbuffer[1] |= (more << IFX_SPI_MORE_BIT) & IFX_SPI_MORE_MASK; | ||
375 | } | ||
376 | |||
377 | /** | ||
378 | * ifx_spi_wakeup_serial - SPI space made | ||
379 | * @port_data: our SPI device | ||
380 | * | ||
381 | * We have emptied the FIFO enough that we want to get more data | ||
382 | * queued into it. Poke the line discipline via tty_wakeup so that | ||
383 | * it will feed us more bits | ||
384 | */ | ||
385 | static void ifx_spi_wakeup_serial(struct ifx_spi_device *ifx_dev) | ||
386 | { | ||
387 | struct tty_struct *tty; | ||
388 | |||
389 | tty = tty_port_tty_get(&ifx_dev->tty_port); | ||
390 | if (!tty) | ||
391 | return; | ||
392 | tty_wakeup(tty); | ||
393 | tty_kref_put(tty); | ||
394 | } | ||
395 | |||
396 | /** | ||
397 | * ifx_spi_prepare_tx_buffer - prepare transmit frame | ||
398 | * @ifx_dev: our SPI device | ||
399 | * | ||
400 | * The transmit buffr needs a header and various other bits of | ||
401 | * information followed by as much data as we can pull from the FIFO | ||
402 | * and transfer. This function formats up a suitable buffer in the | ||
403 | * ifx_dev->tx_buffer | ||
404 | * | ||
405 | * FIXME: performance - should we wake the tty when the queue is half | ||
406 | * empty ? | ||
407 | */ | ||
408 | static int ifx_spi_prepare_tx_buffer(struct ifx_spi_device *ifx_dev) | ||
409 | { | ||
410 | int temp_count; | ||
411 | int queue_length; | ||
412 | int tx_count; | ||
413 | unsigned char *tx_buffer; | ||
414 | |||
415 | tx_buffer = ifx_dev->tx_buffer; | ||
416 | memset(tx_buffer, 0, IFX_SPI_TRANSFER_SIZE); | ||
417 | |||
418 | /* make room for required SPI header */ | ||
419 | tx_buffer += IFX_SPI_HEADER_OVERHEAD; | ||
420 | tx_count = IFX_SPI_HEADER_OVERHEAD; | ||
421 | |||
422 | /* clear to signal no more data if this turns out to be the | ||
423 | * last buffer sent in a sequence */ | ||
424 | ifx_dev->spi_more = 0; | ||
425 | |||
426 | /* if modem cts is set, just send empty buffer */ | ||
427 | if (!ifx_dev->spi_slave_cts) { | ||
428 | /* see if there's tx data */ | ||
429 | queue_length = kfifo_len(&ifx_dev->tx_fifo); | ||
430 | if (queue_length != 0) { | ||
431 | /* data to mux -- see if there's room for it */ | ||
432 | temp_count = min(queue_length, IFX_SPI_PAYLOAD_SIZE); | ||
433 | temp_count = kfifo_out_locked(&ifx_dev->tx_fifo, | ||
434 | tx_buffer, temp_count, | ||
435 | &ifx_dev->fifo_lock); | ||
436 | |||
437 | /* update buffer pointer and data count in message */ | ||
438 | tx_buffer += temp_count; | ||
439 | tx_count += temp_count; | ||
440 | if (temp_count == queue_length) | ||
441 | /* poke port to get more data */ | ||
442 | ifx_spi_wakeup_serial(ifx_dev); | ||
443 | else /* more data in port, use next SPI message */ | ||
444 | ifx_dev->spi_more = 1; | ||
445 | } | ||
446 | } | ||
447 | /* have data and info for header -- set up SPI header in buffer */ | ||
448 | /* spi header needs payload size, not entire buffer size */ | ||
449 | ifx_spi_setup_spi_header(ifx_dev->tx_buffer, | ||
450 | tx_count-IFX_SPI_HEADER_OVERHEAD, | ||
451 | ifx_dev->spi_more); | ||
452 | /* swap actual data in the buffer */ | ||
453 | swap_buf((u16 *)(ifx_dev->tx_buffer), tx_count, | ||
454 | &ifx_dev->tx_buffer[IFX_SPI_TRANSFER_SIZE]); | ||
455 | return tx_count; | ||
456 | } | ||
457 | |||
458 | /** | ||
459 | * ifx_spi_write - line discipline write | ||
460 | * @tty: our tty device | ||
461 | * @buf: pointer to buffer to write (kernel space) | ||
462 | * @count: size of buffer | ||
463 | * | ||
464 | * Write the characters we have been given into the FIFO. If the device | ||
465 | * is not active then activate it, when the SRDY line is asserted back | ||
466 | * this will commence I/O | ||
467 | */ | ||
468 | static int ifx_spi_write(struct tty_struct *tty, const unsigned char *buf, | ||
469 | int count) | ||
470 | { | ||
471 | struct ifx_spi_device *ifx_dev = tty->driver_data; | ||
472 | unsigned char *tmp_buf = (unsigned char *)buf; | ||
473 | int tx_count = kfifo_in_locked(&ifx_dev->tx_fifo, tmp_buf, count, | ||
474 | &ifx_dev->fifo_lock); | ||
475 | mrdy_assert(ifx_dev); | ||
476 | return tx_count; | ||
477 | } | ||
478 | |||
479 | /** | ||
480 | * ifx_spi_chars_in_buffer - line discipline helper | ||
481 | * @tty: our tty device | ||
482 | * | ||
483 | * Report how much data we can accept before we drop bytes. As we use | ||
484 | * a simple FIFO this is nice and easy. | ||
485 | */ | ||
486 | static int ifx_spi_write_room(struct tty_struct *tty) | ||
487 | { | ||
488 | struct ifx_spi_device *ifx_dev = tty->driver_data; | ||
489 | return IFX_SPI_FIFO_SIZE - kfifo_len(&ifx_dev->tx_fifo); | ||
490 | } | ||
491 | |||
492 | /** | ||
493 | * ifx_spi_chars_in_buffer - line discipline helper | ||
494 | * @tty: our tty device | ||
495 | * | ||
496 | * Report how many characters we have buffered. In our case this is the | ||
497 | * number of bytes sitting in our transmit FIFO. | ||
498 | */ | ||
499 | static int ifx_spi_chars_in_buffer(struct tty_struct *tty) | ||
500 | { | ||
501 | struct ifx_spi_device *ifx_dev = tty->driver_data; | ||
502 | return kfifo_len(&ifx_dev->tx_fifo); | ||
503 | } | ||
504 | |||
505 | /** | ||
506 | * ifx_port_hangup | ||
507 | * @port: our tty port | ||
508 | * | ||
509 | * tty port hang up. Called when tty_hangup processing is invoked either | ||
510 | * by loss of carrier, or by software (eg vhangup). Serialized against | ||
511 | * activate/shutdown by the tty layer. | ||
512 | */ | ||
513 | static void ifx_spi_hangup(struct tty_struct *tty) | ||
514 | { | ||
515 | struct ifx_spi_device *ifx_dev = tty->driver_data; | ||
516 | tty_port_hangup(&ifx_dev->tty_port); | ||
517 | } | ||
518 | |||
519 | /** | ||
520 | * ifx_port_activate | ||
521 | * @port: our tty port | ||
522 | * | ||
523 | * tty port activate method - called for first open. Serialized | ||
524 | * with hangup and shutdown by the tty layer. | ||
525 | */ | ||
526 | static int ifx_port_activate(struct tty_port *port, struct tty_struct *tty) | ||
527 | { | ||
528 | struct ifx_spi_device *ifx_dev = | ||
529 | container_of(port, struct ifx_spi_device, tty_port); | ||
530 | |||
531 | /* clear any old data; can't do this in 'close' */ | ||
532 | kfifo_reset(&ifx_dev->tx_fifo); | ||
533 | |||
534 | /* put port data into this tty */ | ||
535 | tty->driver_data = ifx_dev; | ||
536 | |||
537 | /* allows flip string push from int context */ | ||
538 | tty->low_latency = 1; | ||
539 | |||
540 | return 0; | ||
541 | } | ||
542 | |||
543 | /** | ||
544 | * ifx_port_shutdown | ||
545 | * @port: our tty port | ||
546 | * | ||
547 | * tty port shutdown method - called for last port close. Serialized | ||
548 | * with hangup and activate by the tty layer. | ||
549 | */ | ||
550 | static void ifx_port_shutdown(struct tty_port *port) | ||
551 | { | ||
552 | struct ifx_spi_device *ifx_dev = | ||
553 | container_of(port, struct ifx_spi_device, tty_port); | ||
554 | |||
555 | mrdy_set_low(ifx_dev); | ||
556 | clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags); | ||
557 | tasklet_kill(&ifx_dev->io_work_tasklet); | ||
558 | } | ||
559 | |||
560 | static const struct tty_port_operations ifx_tty_port_ops = { | ||
561 | .activate = ifx_port_activate, | ||
562 | .shutdown = ifx_port_shutdown, | ||
563 | }; | ||
564 | |||
565 | static const struct tty_operations ifx_spi_serial_ops = { | ||
566 | .open = ifx_spi_open, | ||
567 | .close = ifx_spi_close, | ||
568 | .write = ifx_spi_write, | ||
569 | .hangup = ifx_spi_hangup, | ||
570 | .write_room = ifx_spi_write_room, | ||
571 | .chars_in_buffer = ifx_spi_chars_in_buffer, | ||
572 | .tiocmget = ifx_spi_tiocmget, | ||
573 | .tiocmset = ifx_spi_tiocmset, | ||
574 | }; | ||
575 | |||
576 | /** | ||
577 | * ifx_spi_insert_fip_string - queue received data | ||
578 | * @ifx_ser: our SPI device | ||
579 | * @chars: buffer we have received | ||
580 | * @size: number of chars reeived | ||
581 | * | ||
582 | * Queue bytes to the tty assuming the tty side is currently open. If | ||
583 | * not the discard the data. | ||
584 | */ | ||
585 | static void ifx_spi_insert_flip_string(struct ifx_spi_device *ifx_dev, | ||
586 | unsigned char *chars, size_t size) | ||
587 | { | ||
588 | struct tty_struct *tty = tty_port_tty_get(&ifx_dev->tty_port); | ||
589 | if (!tty) | ||
590 | return; | ||
591 | tty_insert_flip_string(tty, chars, size); | ||
592 | tty_flip_buffer_push(tty); | ||
593 | tty_kref_put(tty); | ||
594 | } | ||
595 | |||
596 | /** | ||
597 | * ifx_spi_complete - SPI transfer completed | ||
598 | * @ctx: our SPI device | ||
599 | * | ||
600 | * An SPI transfer has completed. Process any received data and kick off | ||
601 | * any further transmits we can commence. | ||
602 | */ | ||
603 | static void ifx_spi_complete(void *ctx) | ||
604 | { | ||
605 | struct ifx_spi_device *ifx_dev = ctx; | ||
606 | struct tty_struct *tty; | ||
607 | struct tty_ldisc *ldisc = NULL; | ||
608 | int length; | ||
609 | int actual_length; | ||
610 | unsigned char more; | ||
611 | unsigned char cts; | ||
612 | int local_write_pending = 0; | ||
613 | int queue_length; | ||
614 | int srdy; | ||
615 | int decode_result; | ||
616 | |||
617 | mrdy_set_low(ifx_dev); | ||
618 | |||
619 | if (!ifx_dev->spi_msg.status) { | ||
620 | /* check header validity, get comm flags */ | ||
621 | swap_buf((u16 *)ifx_dev->rx_buffer, IFX_SPI_HEADER_OVERHEAD, | ||
622 | &ifx_dev->rx_buffer[IFX_SPI_HEADER_OVERHEAD]); | ||
623 | decode_result = ifx_spi_decode_spi_header(ifx_dev->rx_buffer, | ||
624 | &length, &more, &cts); | ||
625 | if (decode_result == IFX_SPI_HEADER_0) { | ||
626 | dev_dbg(&ifx_dev->spi_dev->dev, | ||
627 | "ignore input: invalid header 0"); | ||
628 | ifx_dev->spi_slave_cts = 0; | ||
629 | goto complete_exit; | ||
630 | } else if (decode_result == IFX_SPI_HEADER_F) { | ||
631 | dev_dbg(&ifx_dev->spi_dev->dev, | ||
632 | "ignore input: invalid header F"); | ||
633 | goto complete_exit; | ||
634 | } | ||
635 | |||
636 | ifx_dev->spi_slave_cts = cts; | ||
637 | |||
638 | actual_length = min((unsigned int)length, | ||
639 | ifx_dev->spi_msg.actual_length); | ||
640 | swap_buf((u16 *)(ifx_dev->rx_buffer + IFX_SPI_HEADER_OVERHEAD), | ||
641 | actual_length, | ||
642 | &ifx_dev->rx_buffer[IFX_SPI_TRANSFER_SIZE]); | ||
643 | ifx_spi_insert_flip_string( | ||
644 | ifx_dev, | ||
645 | ifx_dev->rx_buffer + IFX_SPI_HEADER_OVERHEAD, | ||
646 | (size_t)actual_length); | ||
647 | } else { | ||
648 | dev_dbg(&ifx_dev->spi_dev->dev, "SPI transfer error %d", | ||
649 | ifx_dev->spi_msg.status); | ||
650 | } | ||
651 | |||
652 | complete_exit: | ||
653 | if (ifx_dev->write_pending) { | ||
654 | ifx_dev->write_pending = 0; | ||
655 | local_write_pending = 1; | ||
656 | } | ||
657 | |||
658 | clear_bit(IFX_SPI_STATE_IO_IN_PROGRESS, &(ifx_dev->flags)); | ||
659 | |||
660 | queue_length = kfifo_len(&ifx_dev->tx_fifo); | ||
661 | srdy = gpio_get_value(ifx_dev->gpio.srdy); | ||
662 | if (!srdy) | ||
663 | ifx_spi_power_state_clear(ifx_dev, IFX_SPI_POWER_SRDY); | ||
664 | |||
665 | /* schedule output if there is more to do */ | ||
666 | if (test_and_clear_bit(IFX_SPI_STATE_IO_READY, &ifx_dev->flags)) | ||
667 | tasklet_schedule(&ifx_dev->io_work_tasklet); | ||
668 | else { | ||
669 | if (more || ifx_dev->spi_more || queue_length > 0 || | ||
670 | local_write_pending) { | ||
671 | if (ifx_dev->spi_slave_cts) { | ||
672 | if (more) | ||
673 | mrdy_assert(ifx_dev); | ||
674 | } else | ||
675 | mrdy_assert(ifx_dev); | ||
676 | } else { | ||
677 | /* | ||
678 | * poke line discipline driver if any for more data | ||
679 | * may or may not get more data to write | ||
680 | * for now, say not busy | ||
681 | */ | ||
682 | ifx_spi_power_state_clear(ifx_dev, | ||
683 | IFX_SPI_POWER_DATA_PENDING); | ||
684 | tty = tty_port_tty_get(&ifx_dev->tty_port); | ||
685 | if (tty) { | ||
686 | ldisc = tty_ldisc_ref(tty); | ||
687 | if (ldisc) { | ||
688 | ldisc->ops->write_wakeup(tty); | ||
689 | tty_ldisc_deref(ldisc); | ||
690 | } | ||
691 | tty_kref_put(tty); | ||
692 | } | ||
693 | } | ||
694 | } | ||
695 | } | ||
696 | |||
697 | /** | ||
698 | * ifx_spio_io - I/O tasklet | ||
699 | * @data: our SPI device | ||
700 | * | ||
701 | * Queue data for transmission if possible and then kick off the | ||
702 | * transfer. | ||
703 | */ | ||
704 | static void ifx_spi_io(unsigned long data) | ||
705 | { | ||
706 | int retval; | ||
707 | struct ifx_spi_device *ifx_dev = (struct ifx_spi_device *) data; | ||
708 | |||
709 | if (!test_and_set_bit(IFX_SPI_STATE_IO_IN_PROGRESS, &ifx_dev->flags)) { | ||
710 | if (ifx_dev->gpio.unack_srdy_int_nb > 0) | ||
711 | ifx_dev->gpio.unack_srdy_int_nb--; | ||
712 | |||
713 | ifx_spi_prepare_tx_buffer(ifx_dev); | ||
714 | |||
715 | spi_message_init(&ifx_dev->spi_msg); | ||
716 | INIT_LIST_HEAD(&ifx_dev->spi_msg.queue); | ||
717 | |||
718 | ifx_dev->spi_msg.context = ifx_dev; | ||
719 | ifx_dev->spi_msg.complete = ifx_spi_complete; | ||
720 | |||
721 | /* set up our spi transfer */ | ||
722 | /* note len is BYTES, not transfers */ | ||
723 | ifx_dev->spi_xfer.len = IFX_SPI_TRANSFER_SIZE; | ||
724 | ifx_dev->spi_xfer.cs_change = 0; | ||
725 | ifx_dev->spi_xfer.speed_hz = 12500000; | ||
726 | /* ifx_dev->spi_xfer.speed_hz = 390625; */ | ||
727 | ifx_dev->spi_xfer.bits_per_word = spi_b16 ? 16 : 8; | ||
728 | |||
729 | ifx_dev->spi_xfer.tx_buf = ifx_dev->tx_buffer; | ||
730 | ifx_dev->spi_xfer.rx_buf = ifx_dev->rx_buffer; | ||
731 | |||
732 | /* | ||
733 | * setup dma pointers | ||
734 | */ | ||
735 | if (ifx_dev->is_6160) { | ||
736 | ifx_dev->spi_msg.is_dma_mapped = 1; | ||
737 | ifx_dev->tx_dma = ifx_dev->tx_bus; | ||
738 | ifx_dev->rx_dma = ifx_dev->rx_bus; | ||
739 | ifx_dev->spi_xfer.tx_dma = ifx_dev->tx_dma; | ||
740 | ifx_dev->spi_xfer.rx_dma = ifx_dev->rx_dma; | ||
741 | } else { | ||
742 | ifx_dev->spi_msg.is_dma_mapped = 0; | ||
743 | ifx_dev->tx_dma = (dma_addr_t)0; | ||
744 | ifx_dev->rx_dma = (dma_addr_t)0; | ||
745 | ifx_dev->spi_xfer.tx_dma = (dma_addr_t)0; | ||
746 | ifx_dev->spi_xfer.rx_dma = (dma_addr_t)0; | ||
747 | } | ||
748 | |||
749 | spi_message_add_tail(&ifx_dev->spi_xfer, &ifx_dev->spi_msg); | ||
750 | |||
751 | /* Assert MRDY. This may have already been done by the write | ||
752 | * routine. | ||
753 | */ | ||
754 | mrdy_assert(ifx_dev); | ||
755 | |||
756 | retval = spi_async(ifx_dev->spi_dev, &ifx_dev->spi_msg); | ||
757 | if (retval) { | ||
758 | clear_bit(IFX_SPI_STATE_IO_IN_PROGRESS, | ||
759 | &ifx_dev->flags); | ||
760 | tasklet_schedule(&ifx_dev->io_work_tasklet); | ||
761 | return; | ||
762 | } | ||
763 | } else | ||
764 | ifx_dev->write_pending = 1; | ||
765 | } | ||
766 | |||
767 | /** | ||
768 | * ifx_spi_free_port - free up the tty side | ||
769 | * @ifx_dev: IFX device going away | ||
770 | * | ||
771 | * Unregister and free up a port when the device goes away | ||
772 | */ | ||
773 | static void ifx_spi_free_port(struct ifx_spi_device *ifx_dev) | ||
774 | { | ||
775 | if (ifx_dev->tty_dev) | ||
776 | tty_unregister_device(tty_drv, ifx_dev->minor); | ||
777 | kfifo_free(&ifx_dev->tx_fifo); | ||
778 | } | ||
779 | |||
780 | /** | ||
781 | * ifx_spi_create_port - create a new port | ||
782 | * @ifx_dev: our spi device | ||
783 | * | ||
784 | * Allocate and initialise the tty port that goes with this interface | ||
785 | * and add it to the tty layer so that it can be opened. | ||
786 | */ | ||
787 | static int ifx_spi_create_port(struct ifx_spi_device *ifx_dev) | ||
788 | { | ||
789 | int ret = 0; | ||
790 | struct tty_port *pport = &ifx_dev->tty_port; | ||
791 | |||
792 | spin_lock_init(&ifx_dev->fifo_lock); | ||
793 | lockdep_set_class_and_subclass(&ifx_dev->fifo_lock, | ||
794 | &ifx_spi_key, 0); | ||
795 | |||
796 | if (kfifo_alloc(&ifx_dev->tx_fifo, IFX_SPI_FIFO_SIZE, GFP_KERNEL)) { | ||
797 | ret = -ENOMEM; | ||
798 | goto error_ret; | ||
799 | } | ||
800 | |||
801 | pport->ops = &ifx_tty_port_ops; | ||
802 | tty_port_init(pport); | ||
803 | ifx_dev->minor = IFX_SPI_TTY_ID; | ||
804 | ifx_dev->tty_dev = tty_register_device(tty_drv, ifx_dev->minor, | ||
805 | &ifx_dev->spi_dev->dev); | ||
806 | if (IS_ERR(ifx_dev->tty_dev)) { | ||
807 | dev_dbg(&ifx_dev->spi_dev->dev, | ||
808 | "%s: registering tty device failed", __func__); | ||
809 | ret = PTR_ERR(ifx_dev->tty_dev); | ||
810 | goto error_ret; | ||
811 | } | ||
812 | return 0; | ||
813 | |||
814 | error_ret: | ||
815 | ifx_spi_free_port(ifx_dev); | ||
816 | return ret; | ||
817 | } | ||
818 | |||
819 | /** | ||
820 | * ifx_spi_handle_srdy - handle SRDY | ||
821 | * @ifx_dev: device asserting SRDY | ||
822 | * | ||
823 | * Check our device state and see what we need to kick off when SRDY | ||
824 | * is asserted. This usually means killing the timer and firing off the | ||
825 | * I/O processing. | ||
826 | */ | ||
827 | static void ifx_spi_handle_srdy(struct ifx_spi_device *ifx_dev) | ||
828 | { | ||
829 | if (test_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags)) { | ||
830 | del_timer_sync(&ifx_dev->spi_timer); | ||
831 | clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags); | ||
832 | } | ||
833 | |||
834 | ifx_spi_power_state_set(ifx_dev, IFX_SPI_POWER_SRDY); | ||
835 | |||
836 | if (!test_bit(IFX_SPI_STATE_IO_IN_PROGRESS, &ifx_dev->flags)) | ||
837 | tasklet_schedule(&ifx_dev->io_work_tasklet); | ||
838 | else | ||
839 | set_bit(IFX_SPI_STATE_IO_READY, &ifx_dev->flags); | ||
840 | } | ||
841 | |||
842 | /** | ||
843 | * ifx_spi_srdy_interrupt - SRDY asserted | ||
844 | * @irq: our IRQ number | ||
845 | * @dev: our ifx device | ||
846 | * | ||
847 | * The modem asserted SRDY. Handle the srdy event | ||
848 | */ | ||
849 | static irqreturn_t ifx_spi_srdy_interrupt(int irq, void *dev) | ||
850 | { | ||
851 | struct ifx_spi_device *ifx_dev = dev; | ||
852 | ifx_dev->gpio.unack_srdy_int_nb++; | ||
853 | ifx_spi_handle_srdy(ifx_dev); | ||
854 | return IRQ_HANDLED; | ||
855 | } | ||
856 | |||
857 | /** | ||
858 | * ifx_spi_reset_interrupt - Modem has changed reset state | ||
859 | * @irq: interrupt number | ||
860 | * @dev: our device pointer | ||
861 | * | ||
862 | * The modem has either entered or left reset state. Check the GPIO | ||
863 | * line to see which. | ||
864 | * | ||
865 | * FIXME: review locking on MR_INPROGRESS versus | ||
866 | * parallel unsolicited reset/solicited reset | ||
867 | */ | ||
868 | static irqreturn_t ifx_spi_reset_interrupt(int irq, void *dev) | ||
869 | { | ||
870 | struct ifx_spi_device *ifx_dev = dev; | ||
871 | int val = gpio_get_value(ifx_dev->gpio.reset_out); | ||
872 | int solreset = test_bit(MR_START, &ifx_dev->mdm_reset_state); | ||
873 | |||
874 | if (val == 0) { | ||
875 | /* entered reset */ | ||
876 | set_bit(MR_INPROGRESS, &ifx_dev->mdm_reset_state); | ||
877 | if (!solreset) { | ||
878 | /* unsolicited reset */ | ||
879 | ifx_spi_ttyhangup(ifx_dev); | ||
880 | } | ||
881 | } else { | ||
882 | /* exited reset */ | ||
883 | clear_bit(MR_INPROGRESS, &ifx_dev->mdm_reset_state); | ||
884 | if (solreset) { | ||
885 | set_bit(MR_COMPLETE, &ifx_dev->mdm_reset_state); | ||
886 | wake_up(&ifx_dev->mdm_reset_wait); | ||
887 | } | ||
888 | } | ||
889 | return IRQ_HANDLED; | ||
890 | } | ||
891 | |||
892 | /** | ||
893 | * ifx_spi_free_device - free device | ||
894 | * @ifx_dev: device to free | ||
895 | * | ||
896 | * Free the IFX device | ||
897 | */ | ||
898 | static void ifx_spi_free_device(struct ifx_spi_device *ifx_dev) | ||
899 | { | ||
900 | ifx_spi_free_port(ifx_dev); | ||
901 | dma_free_coherent(&ifx_dev->spi_dev->dev, | ||
902 | IFX_SPI_TRANSFER_SIZE, | ||
903 | ifx_dev->tx_buffer, | ||
904 | ifx_dev->tx_bus); | ||
905 | dma_free_coherent(&ifx_dev->spi_dev->dev, | ||
906 | IFX_SPI_TRANSFER_SIZE, | ||
907 | ifx_dev->rx_buffer, | ||
908 | ifx_dev->rx_bus); | ||
909 | } | ||
910 | |||
911 | /** | ||
912 | * ifx_spi_reset - reset modem | ||
913 | * @ifx_dev: modem to reset | ||
914 | * | ||
915 | * Perform a reset on the modem | ||
916 | */ | ||
917 | static int ifx_spi_reset(struct ifx_spi_device *ifx_dev) | ||
918 | { | ||
919 | int ret; | ||
920 | /* | ||
921 | * set up modem power, reset | ||
922 | * | ||
923 | * delays are required on some platforms for the modem | ||
924 | * to reset properly | ||
925 | */ | ||
926 | set_bit(MR_START, &ifx_dev->mdm_reset_state); | ||
927 | gpio_set_value(ifx_dev->gpio.po, 0); | ||
928 | gpio_set_value(ifx_dev->gpio.reset, 0); | ||
929 | msleep(25); | ||
930 | gpio_set_value(ifx_dev->gpio.reset, 1); | ||
931 | msleep(1); | ||
932 | gpio_set_value(ifx_dev->gpio.po, 1); | ||
933 | msleep(1); | ||
934 | gpio_set_value(ifx_dev->gpio.po, 0); | ||
935 | ret = wait_event_timeout(ifx_dev->mdm_reset_wait, | ||
936 | test_bit(MR_COMPLETE, | ||
937 | &ifx_dev->mdm_reset_state), | ||
938 | IFX_RESET_TIMEOUT); | ||
939 | if (!ret) | ||
940 | dev_warn(&ifx_dev->spi_dev->dev, "Modem reset timeout: (state:%lx)", | ||
941 | ifx_dev->mdm_reset_state); | ||
942 | |||
943 | ifx_dev->mdm_reset_state = 0; | ||
944 | return ret; | ||
945 | } | ||
946 | |||
947 | /** | ||
948 | * ifx_spi_spi_probe - probe callback | ||
949 | * @spi: our possible matching SPI device | ||
950 | * | ||
951 | * Probe for a 6x60 modem on SPI bus. Perform any needed device and | ||
952 | * GPIO setup. | ||
953 | * | ||
954 | * FIXME: | ||
955 | * - Support for multiple devices | ||
956 | * - Split out MID specific GPIO handling eventually | ||
957 | */ | ||
958 | |||
959 | static int ifx_spi_spi_probe(struct spi_device *spi) | ||
960 | { | ||
961 | int ret; | ||
962 | int srdy; | ||
963 | struct ifx_modem_platform_data *pl_data = NULL; | ||
964 | struct ifx_spi_device *ifx_dev; | ||
965 | |||
966 | if (saved_ifx_dev) { | ||
967 | dev_dbg(&spi->dev, "ignoring subsequent detection"); | ||
968 | return -ENODEV; | ||
969 | } | ||
970 | |||
971 | /* initialize structure to hold our device variables */ | ||
972 | ifx_dev = kzalloc(sizeof(struct ifx_spi_device), GFP_KERNEL); | ||
973 | if (!ifx_dev) { | ||
974 | dev_err(&spi->dev, "spi device allocation failed"); | ||
975 | return -ENOMEM; | ||
976 | } | ||
977 | saved_ifx_dev = ifx_dev; | ||
978 | ifx_dev->spi_dev = spi; | ||
979 | clear_bit(IFX_SPI_STATE_IO_IN_PROGRESS, &ifx_dev->flags); | ||
980 | spin_lock_init(&ifx_dev->write_lock); | ||
981 | spin_lock_init(&ifx_dev->power_lock); | ||
982 | ifx_dev->power_status = 0; | ||
983 | init_timer(&ifx_dev->spi_timer); | ||
984 | ifx_dev->spi_timer.function = ifx_spi_timeout; | ||
985 | ifx_dev->spi_timer.data = (unsigned long)ifx_dev; | ||
986 | ifx_dev->is_6160 = pl_data->is_6160; | ||
987 | |||
988 | /* ensure SPI protocol flags are initialized to enable transfer */ | ||
989 | ifx_dev->spi_more = 0; | ||
990 | ifx_dev->spi_slave_cts = 0; | ||
991 | |||
992 | /*initialize transfer and dma buffers */ | ||
993 | ifx_dev->tx_buffer = dma_alloc_coherent(&ifx_dev->spi_dev->dev, | ||
994 | IFX_SPI_TRANSFER_SIZE, | ||
995 | &ifx_dev->tx_bus, | ||
996 | GFP_KERNEL); | ||
997 | if (!ifx_dev->tx_buffer) { | ||
998 | dev_err(&spi->dev, "DMA-TX buffer allocation failed"); | ||
999 | ret = -ENOMEM; | ||
1000 | goto error_ret; | ||
1001 | } | ||
1002 | ifx_dev->rx_buffer = dma_alloc_coherent(&ifx_dev->spi_dev->dev, | ||
1003 | IFX_SPI_TRANSFER_SIZE, | ||
1004 | &ifx_dev->rx_bus, | ||
1005 | GFP_KERNEL); | ||
1006 | if (!ifx_dev->rx_buffer) { | ||
1007 | dev_err(&spi->dev, "DMA-RX buffer allocation failed"); | ||
1008 | ret = -ENOMEM; | ||
1009 | goto error_ret; | ||
1010 | } | ||
1011 | |||
1012 | /* initialize waitq for modem reset */ | ||
1013 | init_waitqueue_head(&ifx_dev->mdm_reset_wait); | ||
1014 | |||
1015 | spi_set_drvdata(spi, ifx_dev); | ||
1016 | tasklet_init(&ifx_dev->io_work_tasklet, ifx_spi_io, | ||
1017 | (unsigned long)ifx_dev); | ||
1018 | |||
1019 | set_bit(IFX_SPI_STATE_PRESENT, &ifx_dev->flags); | ||
1020 | |||
1021 | /* create our tty port */ | ||
1022 | ret = ifx_spi_create_port(ifx_dev); | ||
1023 | if (ret != 0) { | ||
1024 | dev_err(&spi->dev, "create default tty port failed"); | ||
1025 | goto error_ret; | ||
1026 | } | ||
1027 | |||
1028 | pl_data = (struct ifx_modem_platform_data *)spi->dev.platform_data; | ||
1029 | if (pl_data) { | ||
1030 | ifx_dev->gpio.reset = pl_data->rst_pmu; | ||
1031 | ifx_dev->gpio.po = pl_data->pwr_on; | ||
1032 | ifx_dev->gpio.mrdy = pl_data->mrdy; | ||
1033 | ifx_dev->gpio.srdy = pl_data->srdy; | ||
1034 | ifx_dev->gpio.reset_out = pl_data->rst_out; | ||
1035 | } else { | ||
1036 | dev_err(&spi->dev, "missing platform data!"); | ||
1037 | ret = -ENODEV; | ||
1038 | goto error_ret; | ||
1039 | } | ||
1040 | |||
1041 | dev_info(&spi->dev, "gpios %d, %d, %d, %d, %d", | ||
1042 | ifx_dev->gpio.reset, ifx_dev->gpio.po, ifx_dev->gpio.mrdy, | ||
1043 | ifx_dev->gpio.srdy, ifx_dev->gpio.reset_out); | ||
1044 | |||
1045 | /* Configure gpios */ | ||
1046 | ret = gpio_request(ifx_dev->gpio.reset, "ifxModem"); | ||
1047 | if (ret < 0) { | ||
1048 | dev_err(&spi->dev, "Unable to allocate GPIO%d (RESET)", | ||
1049 | ifx_dev->gpio.reset); | ||
1050 | goto error_ret; | ||
1051 | } | ||
1052 | ret += gpio_direction_output(ifx_dev->gpio.reset, 0); | ||
1053 | ret += gpio_export(ifx_dev->gpio.reset, 1); | ||
1054 | if (ret) { | ||
1055 | dev_err(&spi->dev, "Unable to configure GPIO%d (RESET)", | ||
1056 | ifx_dev->gpio.reset); | ||
1057 | ret = -EBUSY; | ||
1058 | goto error_ret2; | ||
1059 | } | ||
1060 | |||
1061 | ret = gpio_request(ifx_dev->gpio.po, "ifxModem"); | ||
1062 | ret += gpio_direction_output(ifx_dev->gpio.po, 0); | ||
1063 | ret += gpio_export(ifx_dev->gpio.po, 1); | ||
1064 | if (ret) { | ||
1065 | dev_err(&spi->dev, "Unable to configure GPIO%d (ON)", | ||
1066 | ifx_dev->gpio.po); | ||
1067 | ret = -EBUSY; | ||
1068 | goto error_ret3; | ||
1069 | } | ||
1070 | |||
1071 | ret = gpio_request(ifx_dev->gpio.mrdy, "ifxModem"); | ||
1072 | if (ret < 0) { | ||
1073 | dev_err(&spi->dev, "Unable to allocate GPIO%d (MRDY)", | ||
1074 | ifx_dev->gpio.mrdy); | ||
1075 | goto error_ret3; | ||
1076 | } | ||
1077 | ret += gpio_export(ifx_dev->gpio.mrdy, 1); | ||
1078 | ret += gpio_direction_output(ifx_dev->gpio.mrdy, 0); | ||
1079 | if (ret) { | ||
1080 | dev_err(&spi->dev, "Unable to configure GPIO%d (MRDY)", | ||
1081 | ifx_dev->gpio.mrdy); | ||
1082 | ret = -EBUSY; | ||
1083 | goto error_ret4; | ||
1084 | } | ||
1085 | |||
1086 | ret = gpio_request(ifx_dev->gpio.srdy, "ifxModem"); | ||
1087 | if (ret < 0) { | ||
1088 | dev_err(&spi->dev, "Unable to allocate GPIO%d (SRDY)", | ||
1089 | ifx_dev->gpio.srdy); | ||
1090 | ret = -EBUSY; | ||
1091 | goto error_ret4; | ||
1092 | } | ||
1093 | ret += gpio_export(ifx_dev->gpio.srdy, 1); | ||
1094 | ret += gpio_direction_input(ifx_dev->gpio.srdy); | ||
1095 | if (ret) { | ||
1096 | dev_err(&spi->dev, "Unable to configure GPIO%d (SRDY)", | ||
1097 | ifx_dev->gpio.srdy); | ||
1098 | ret = -EBUSY; | ||
1099 | goto error_ret5; | ||
1100 | } | ||
1101 | |||
1102 | ret = gpio_request(ifx_dev->gpio.reset_out, "ifxModem"); | ||
1103 | if (ret < 0) { | ||
1104 | dev_err(&spi->dev, "Unable to allocate GPIO%d (RESET_OUT)", | ||
1105 | ifx_dev->gpio.reset_out); | ||
1106 | goto error_ret5; | ||
1107 | } | ||
1108 | ret += gpio_export(ifx_dev->gpio.reset_out, 1); | ||
1109 | ret += gpio_direction_input(ifx_dev->gpio.reset_out); | ||
1110 | if (ret) { | ||
1111 | dev_err(&spi->dev, "Unable to configure GPIO%d (RESET_OUT)", | ||
1112 | ifx_dev->gpio.reset_out); | ||
1113 | ret = -EBUSY; | ||
1114 | goto error_ret6; | ||
1115 | } | ||
1116 | |||
1117 | ret = request_irq(gpio_to_irq(ifx_dev->gpio.reset_out), | ||
1118 | ifx_spi_reset_interrupt, | ||
1119 | IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING, DRVNAME, | ||
1120 | (void *)ifx_dev); | ||
1121 | if (ret) { | ||
1122 | dev_err(&spi->dev, "Unable to get irq %x\n", | ||
1123 | gpio_to_irq(ifx_dev->gpio.reset_out)); | ||
1124 | goto error_ret6; | ||
1125 | } | ||
1126 | |||
1127 | ret = ifx_spi_reset(ifx_dev); | ||
1128 | |||
1129 | ret = request_irq(gpio_to_irq(ifx_dev->gpio.srdy), | ||
1130 | ifx_spi_srdy_interrupt, | ||
1131 | IRQF_TRIGGER_RISING, DRVNAME, | ||
1132 | (void *)ifx_dev); | ||
1133 | if (ret) { | ||
1134 | dev_err(&spi->dev, "Unable to get irq %x", | ||
1135 | gpio_to_irq(ifx_dev->gpio.srdy)); | ||
1136 | goto error_ret7; | ||
1137 | } | ||
1138 | |||
1139 | /* set pm runtime power state and register with power system */ | ||
1140 | pm_runtime_set_active(&spi->dev); | ||
1141 | pm_runtime_enable(&spi->dev); | ||
1142 | |||
1143 | /* handle case that modem is already signaling SRDY */ | ||
1144 | /* no outgoing tty open at this point, this just satisfies the | ||
1145 | * modem's read and should reset communication properly | ||
1146 | */ | ||
1147 | srdy = gpio_get_value(ifx_dev->gpio.srdy); | ||
1148 | |||
1149 | if (srdy) { | ||
1150 | mrdy_assert(ifx_dev); | ||
1151 | ifx_spi_handle_srdy(ifx_dev); | ||
1152 | } else | ||
1153 | mrdy_set_low(ifx_dev); | ||
1154 | return 0; | ||
1155 | |||
1156 | error_ret7: | ||
1157 | free_irq(gpio_to_irq(ifx_dev->gpio.reset_out), (void *)ifx_dev); | ||
1158 | error_ret6: | ||
1159 | gpio_free(ifx_dev->gpio.srdy); | ||
1160 | error_ret5: | ||
1161 | gpio_free(ifx_dev->gpio.mrdy); | ||
1162 | error_ret4: | ||
1163 | gpio_free(ifx_dev->gpio.reset); | ||
1164 | error_ret3: | ||
1165 | gpio_free(ifx_dev->gpio.po); | ||
1166 | error_ret2: | ||
1167 | gpio_free(ifx_dev->gpio.reset_out); | ||
1168 | error_ret: | ||
1169 | ifx_spi_free_device(ifx_dev); | ||
1170 | saved_ifx_dev = NULL; | ||
1171 | return ret; | ||
1172 | } | ||
1173 | |||
1174 | /** | ||
1175 | * ifx_spi_spi_remove - SPI device was removed | ||
1176 | * @spi: SPI device | ||
1177 | * | ||
1178 | * FIXME: We should be shutting the device down here not in | ||
1179 | * the module unload path. | ||
1180 | */ | ||
1181 | |||
1182 | static int ifx_spi_spi_remove(struct spi_device *spi) | ||
1183 | { | ||
1184 | struct ifx_spi_device *ifx_dev = spi_get_drvdata(spi); | ||
1185 | /* stop activity */ | ||
1186 | tasklet_kill(&ifx_dev->io_work_tasklet); | ||
1187 | /* free irq */ | ||
1188 | free_irq(gpio_to_irq(ifx_dev->gpio.reset_out), (void *)ifx_dev); | ||
1189 | free_irq(gpio_to_irq(ifx_dev->gpio.srdy), (void *)ifx_dev); | ||
1190 | |||
1191 | gpio_free(ifx_dev->gpio.srdy); | ||
1192 | gpio_free(ifx_dev->gpio.mrdy); | ||
1193 | gpio_free(ifx_dev->gpio.reset); | ||
1194 | gpio_free(ifx_dev->gpio.po); | ||
1195 | gpio_free(ifx_dev->gpio.reset_out); | ||
1196 | |||
1197 | /* free allocations */ | ||
1198 | ifx_spi_free_device(ifx_dev); | ||
1199 | |||
1200 | saved_ifx_dev = NULL; | ||
1201 | return 0; | ||
1202 | } | ||
1203 | |||
1204 | /** | ||
1205 | * ifx_spi_spi_shutdown - called on SPI shutdown | ||
1206 | * @spi: SPI device | ||
1207 | * | ||
1208 | * No action needs to be taken here | ||
1209 | */ | ||
1210 | |||
1211 | static void ifx_spi_spi_shutdown(struct spi_device *spi) | ||
1212 | { | ||
1213 | } | ||
1214 | |||
1215 | /* | ||
1216 | * various suspends and resumes have nothing to do | ||
1217 | * no hardware to save state for | ||
1218 | */ | ||
1219 | |||
1220 | /** | ||
1221 | * ifx_spi_spi_suspend - suspend SPI on system suspend | ||
1222 | * @dev: device being suspended | ||
1223 | * | ||
1224 | * Suspend the SPI side. No action needed on Intel MID platforms, may | ||
1225 | * need extending for other systems. | ||
1226 | */ | ||
1227 | static int ifx_spi_spi_suspend(struct spi_device *spi, pm_message_t msg) | ||
1228 | { | ||
1229 | return 0; | ||
1230 | } | ||
1231 | |||
1232 | /** | ||
1233 | * ifx_spi_spi_resume - resume SPI side on system resume | ||
1234 | * @dev: device being suspended | ||
1235 | * | ||
1236 | * Suspend the SPI side. No action needed on Intel MID platforms, may | ||
1237 | * need extending for other systems. | ||
1238 | */ | ||
1239 | static int ifx_spi_spi_resume(struct spi_device *spi) | ||
1240 | { | ||
1241 | return 0; | ||
1242 | } | ||
1243 | |||
1244 | /** | ||
1245 | * ifx_spi_pm_suspend - suspend modem on system suspend | ||
1246 | * @dev: device being suspended | ||
1247 | * | ||
1248 | * Suspend the modem. No action needed on Intel MID platforms, may | ||
1249 | * need extending for other systems. | ||
1250 | */ | ||
1251 | static int ifx_spi_pm_suspend(struct device *dev) | ||
1252 | { | ||
1253 | return 0; | ||
1254 | } | ||
1255 | |||
1256 | /** | ||
1257 | * ifx_spi_pm_resume - resume modem on system resume | ||
1258 | * @dev: device being suspended | ||
1259 | * | ||
1260 | * Allow the modem to resume. No action needed. | ||
1261 | * | ||
1262 | * FIXME: do we need to reset anything here ? | ||
1263 | */ | ||
1264 | static int ifx_spi_pm_resume(struct device *dev) | ||
1265 | { | ||
1266 | return 0; | ||
1267 | } | ||
1268 | |||
1269 | /** | ||
1270 | * ifx_spi_pm_runtime_resume - suspend modem | ||
1271 | * @dev: device being suspended | ||
1272 | * | ||
1273 | * Allow the modem to resume. No action needed. | ||
1274 | */ | ||
1275 | static int ifx_spi_pm_runtime_resume(struct device *dev) | ||
1276 | { | ||
1277 | return 0; | ||
1278 | } | ||
1279 | |||
1280 | /** | ||
1281 | * ifx_spi_pm_runtime_suspend - suspend modem | ||
1282 | * @dev: device being suspended | ||
1283 | * | ||
1284 | * Allow the modem to suspend and thus suspend to continue up the | ||
1285 | * device tree. | ||
1286 | */ | ||
1287 | static int ifx_spi_pm_runtime_suspend(struct device *dev) | ||
1288 | { | ||
1289 | return 0; | ||
1290 | } | ||
1291 | |||
1292 | /** | ||
1293 | * ifx_spi_pm_runtime_idle - check if modem idle | ||
1294 | * @dev: our device | ||
1295 | * | ||
1296 | * Check conditions and queue runtime suspend if idle. | ||
1297 | */ | ||
1298 | static int ifx_spi_pm_runtime_idle(struct device *dev) | ||
1299 | { | ||
1300 | struct spi_device *spi = to_spi_device(dev); | ||
1301 | struct ifx_spi_device *ifx_dev = spi_get_drvdata(spi); | ||
1302 | |||
1303 | if (!ifx_dev->power_status) | ||
1304 | pm_runtime_suspend(dev); | ||
1305 | |||
1306 | return 0; | ||
1307 | } | ||
1308 | |||
1309 | static const struct dev_pm_ops ifx_spi_pm = { | ||
1310 | .resume = ifx_spi_pm_resume, | ||
1311 | .suspend = ifx_spi_pm_suspend, | ||
1312 | .runtime_resume = ifx_spi_pm_runtime_resume, | ||
1313 | .runtime_suspend = ifx_spi_pm_runtime_suspend, | ||
1314 | .runtime_idle = ifx_spi_pm_runtime_idle | ||
1315 | }; | ||
1316 | |||
1317 | static const struct spi_device_id ifx_id_table[] = { | ||
1318 | {"ifx6160", 0}, | ||
1319 | {"ifx6260", 0}, | ||
1320 | { } | ||
1321 | }; | ||
1322 | MODULE_DEVICE_TABLE(spi, ifx_id_table); | ||
1323 | |||
1324 | /* spi operations */ | ||
1325 | static const struct spi_driver ifx_spi_driver_6160 = { | ||
1326 | .driver = { | ||
1327 | .name = "ifx6160", | ||
1328 | .bus = &spi_bus_type, | ||
1329 | .pm = &ifx_spi_pm, | ||
1330 | .owner = THIS_MODULE}, | ||
1331 | .probe = ifx_spi_spi_probe, | ||
1332 | .shutdown = ifx_spi_spi_shutdown, | ||
1333 | .remove = __devexit_p(ifx_spi_spi_remove), | ||
1334 | .suspend = ifx_spi_spi_suspend, | ||
1335 | .resume = ifx_spi_spi_resume, | ||
1336 | .id_table = ifx_id_table | ||
1337 | }; | ||
1338 | |||
1339 | /** | ||
1340 | * ifx_spi_exit - module exit | ||
1341 | * | ||
1342 | * Unload the module. | ||
1343 | */ | ||
1344 | |||
1345 | static void __exit ifx_spi_exit(void) | ||
1346 | { | ||
1347 | /* unregister */ | ||
1348 | tty_unregister_driver(tty_drv); | ||
1349 | spi_unregister_driver((void *)&ifx_spi_driver_6160); | ||
1350 | } | ||
1351 | |||
1352 | /** | ||
1353 | * ifx_spi_init - module entry point | ||
1354 | * | ||
1355 | * Initialise the SPI and tty interfaces for the IFX SPI driver | ||
1356 | * We need to initialize upper-edge spi driver after the tty | ||
1357 | * driver because otherwise the spi probe will race | ||
1358 | */ | ||
1359 | |||
1360 | static int __init ifx_spi_init(void) | ||
1361 | { | ||
1362 | int result; | ||
1363 | |||
1364 | tty_drv = alloc_tty_driver(1); | ||
1365 | if (!tty_drv) { | ||
1366 | pr_err("%s: alloc_tty_driver failed", DRVNAME); | ||
1367 | return -ENOMEM; | ||
1368 | } | ||
1369 | |||
1370 | tty_drv->magic = TTY_DRIVER_MAGIC; | ||
1371 | tty_drv->owner = THIS_MODULE; | ||
1372 | tty_drv->driver_name = DRVNAME; | ||
1373 | tty_drv->name = TTYNAME; | ||
1374 | tty_drv->minor_start = IFX_SPI_TTY_ID; | ||
1375 | tty_drv->num = 1; | ||
1376 | tty_drv->type = TTY_DRIVER_TYPE_SERIAL; | ||
1377 | tty_drv->subtype = SERIAL_TYPE_NORMAL; | ||
1378 | tty_drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | ||
1379 | tty_drv->init_termios = tty_std_termios; | ||
1380 | |||
1381 | tty_set_operations(tty_drv, &ifx_spi_serial_ops); | ||
1382 | |||
1383 | result = tty_register_driver(tty_drv); | ||
1384 | if (result) { | ||
1385 | pr_err("%s: tty_register_driver failed(%d)", | ||
1386 | DRVNAME, result); | ||
1387 | put_tty_driver(tty_drv); | ||
1388 | return result; | ||
1389 | } | ||
1390 | |||
1391 | result = spi_register_driver((void *)&ifx_spi_driver_6160); | ||
1392 | if (result) { | ||
1393 | pr_err("%s: spi_register_driver failed(%d)", | ||
1394 | DRVNAME, result); | ||
1395 | tty_unregister_driver(tty_drv); | ||
1396 | } | ||
1397 | return result; | ||
1398 | } | ||
1399 | |||
1400 | module_init(ifx_spi_init); | ||
1401 | module_exit(ifx_spi_exit); | ||
1402 | |||
1403 | MODULE_AUTHOR("Intel"); | ||
1404 | MODULE_DESCRIPTION("IFX6x60 spi driver"); | ||
1405 | MODULE_LICENSE("GPL"); | ||
1406 | MODULE_INFO(Version, "0.1-IFX6x60"); | ||
diff --git a/drivers/serial/ifx6x60.h b/drivers/serial/ifx6x60.h new file mode 100644 index 000000000000..deb7b8d977dc --- /dev/null +++ b/drivers/serial/ifx6x60.h | |||
@@ -0,0 +1,129 @@ | |||
1 | /**************************************************************************** | ||
2 | * | ||
3 | * Driver for the IFX spi modem. | ||
4 | * | ||
5 | * Copyright (C) 2009, 2010 Intel Corp | ||
6 | * Jim Stanley <jim.stanley@intel.com> | ||
7 | * | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, | ||
21 | * USA | ||
22 | * | ||
23 | * | ||
24 | * | ||
25 | *****************************************************************************/ | ||
26 | #ifndef _IFX6X60_H | ||
27 | #define _IFX6X60_H | ||
28 | |||
29 | #define DRVNAME "ifx6x60" | ||
30 | #define TTYNAME "ttyIFX" | ||
31 | |||
32 | /* #define IFX_THROTTLE_CODE */ | ||
33 | |||
34 | #define IFX_SPI_MAX_MINORS 1 | ||
35 | #define IFX_SPI_TRANSFER_SIZE 2048 | ||
36 | #define IFX_SPI_FIFO_SIZE 4096 | ||
37 | |||
38 | #define IFX_SPI_HEADER_OVERHEAD 4 | ||
39 | #define IFX_RESET_TIMEOUT msecs_to_jiffies(50) | ||
40 | |||
41 | /* device flags bitfield definitions */ | ||
42 | #define IFX_SPI_STATE_PRESENT 0 | ||
43 | #define IFX_SPI_STATE_IO_IN_PROGRESS 1 | ||
44 | #define IFX_SPI_STATE_IO_READY 2 | ||
45 | #define IFX_SPI_STATE_TIMER_PENDING 3 | ||
46 | |||
47 | /* flow control bitfields */ | ||
48 | #define IFX_SPI_DCD 0 | ||
49 | #define IFX_SPI_CTS 1 | ||
50 | #define IFX_SPI_DSR 2 | ||
51 | #define IFX_SPI_RI 3 | ||
52 | #define IFX_SPI_DTR 4 | ||
53 | #define IFX_SPI_RTS 5 | ||
54 | #define IFX_SPI_TX_FC 6 | ||
55 | #define IFX_SPI_RX_FC 7 | ||
56 | #define IFX_SPI_UPDATE 8 | ||
57 | |||
58 | #define IFX_SPI_PAYLOAD_SIZE (IFX_SPI_TRANSFER_SIZE - \ | ||
59 | IFX_SPI_HEADER_OVERHEAD) | ||
60 | |||
61 | #define IFX_SPI_IRQ_TYPE DETECT_EDGE_RISING | ||
62 | #define IFX_SPI_GPIO_TARGET 0 | ||
63 | #define IFX_SPI_GPIO0 0x105 | ||
64 | |||
65 | #define IFX_SPI_STATUS_TIMEOUT (2000*HZ) | ||
66 | |||
67 | /* values for bits in power status byte */ | ||
68 | #define IFX_SPI_POWER_DATA_PENDING 1 | ||
69 | #define IFX_SPI_POWER_SRDY 2 | ||
70 | |||
71 | struct ifx_spi_device { | ||
72 | /* Our SPI device */ | ||
73 | struct spi_device *spi_dev; | ||
74 | |||
75 | /* Port specific data */ | ||
76 | struct kfifo tx_fifo; | ||
77 | spinlock_t fifo_lock; | ||
78 | unsigned long signal_state; | ||
79 | |||
80 | /* TTY Layer logic */ | ||
81 | struct tty_port tty_port; | ||
82 | struct device *tty_dev; | ||
83 | int minor; | ||
84 | |||
85 | /* Low level I/O work */ | ||
86 | struct tasklet_struct io_work_tasklet; | ||
87 | unsigned long flags; | ||
88 | dma_addr_t rx_dma; | ||
89 | dma_addr_t tx_dma; | ||
90 | |||
91 | int is_6160; /* Modem type */ | ||
92 | |||
93 | spinlock_t write_lock; | ||
94 | int write_pending; | ||
95 | spinlock_t power_lock; | ||
96 | unsigned char power_status; | ||
97 | |||
98 | unsigned char *rx_buffer; | ||
99 | unsigned char *tx_buffer; | ||
100 | dma_addr_t rx_bus; | ||
101 | dma_addr_t tx_bus; | ||
102 | unsigned char spi_more; | ||
103 | unsigned char spi_slave_cts; | ||
104 | |||
105 | struct timer_list spi_timer; | ||
106 | |||
107 | struct spi_message spi_msg; | ||
108 | struct spi_transfer spi_xfer; | ||
109 | |||
110 | struct { | ||
111 | /* gpio lines */ | ||
112 | unsigned short srdy; /* slave-ready gpio */ | ||
113 | unsigned short mrdy; /* master-ready gpio */ | ||
114 | unsigned short reset; /* modem-reset gpio */ | ||
115 | unsigned short po; /* modem-on gpio */ | ||
116 | unsigned short reset_out; /* modem-in-reset gpio */ | ||
117 | /* state/stats */ | ||
118 | int unack_srdy_int_nb; | ||
119 | } gpio; | ||
120 | |||
121 | /* modem reset */ | ||
122 | unsigned long mdm_reset_state; | ||
123 | #define MR_START 0 | ||
124 | #define MR_INPROGRESS 1 | ||
125 | #define MR_COMPLETE 2 | ||
126 | wait_queue_head_t mdm_reset_wait; | ||
127 | }; | ||
128 | |||
129 | #endif /* _IFX6X60_H */ | ||
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 5d7b58f1fe42..dfcf4b1878aa 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <linux/clk.h> | 46 | #include <linux/clk.h> |
47 | #include <linux/delay.h> | 47 | #include <linux/delay.h> |
48 | #include <linux/rational.h> | 48 | #include <linux/rational.h> |
49 | #include <linux/slab.h> | ||
49 | 50 | ||
50 | #include <asm/io.h> | 51 | #include <asm/io.h> |
51 | #include <asm/irq.h> | 52 | #include <asm/irq.h> |
@@ -67,21 +68,8 @@ | |||
67 | #define UBIR 0xa4 /* BRM Incremental Register */ | 68 | #define UBIR 0xa4 /* BRM Incremental Register */ |
68 | #define UBMR 0xa8 /* BRM Modulator Register */ | 69 | #define UBMR 0xa8 /* BRM Modulator Register */ |
69 | #define UBRC 0xac /* Baud Rate Count Register */ | 70 | #define UBRC 0xac /* Baud Rate Count Register */ |
70 | #if defined CONFIG_ARCH_MX3 || defined CONFIG_ARCH_MX2 | 71 | #define MX2_ONEMS 0xb0 /* One Millisecond register */ |
71 | #define ONEMS 0xb0 /* One Millisecond register */ | 72 | #define UTS (cpu_is_mx1() ? 0xd0 : 0xb4) /* UART Test Register */ |
72 | #define UTS 0xb4 /* UART Test Register */ | ||
73 | #endif | ||
74 | #ifdef CONFIG_ARCH_MX1 | ||
75 | #define BIPR1 0xb0 /* Incremental Preset Register 1 */ | ||
76 | #define BIPR2 0xb4 /* Incremental Preset Register 2 */ | ||
77 | #define BIPR3 0xb8 /* Incremental Preset Register 3 */ | ||
78 | #define BIPR4 0xbc /* Incremental Preset Register 4 */ | ||
79 | #define BMPR1 0xc0 /* BRM Modulator Register 1 */ | ||
80 | #define BMPR2 0xc4 /* BRM Modulator Register 2 */ | ||
81 | #define BMPR3 0xc8 /* BRM Modulator Register 3 */ | ||
82 | #define BMPR4 0xcc /* BRM Modulator Register 4 */ | ||
83 | #define UTS 0xd0 /* UART Test Register */ | ||
84 | #endif | ||
85 | 73 | ||
86 | /* UART Control Register Bit Fields.*/ | 74 | /* UART Control Register Bit Fields.*/ |
87 | #define URXD_CHARRDY (1<<15) | 75 | #define URXD_CHARRDY (1<<15) |
@@ -101,12 +89,7 @@ | |||
101 | #define UCR1_RTSDEN (1<<5) /* RTS delta interrupt enable */ | 89 | #define UCR1_RTSDEN (1<<5) /* RTS delta interrupt enable */ |
102 | #define UCR1_SNDBRK (1<<4) /* Send break */ | 90 | #define UCR1_SNDBRK (1<<4) /* Send break */ |
103 | #define UCR1_TDMAEN (1<<3) /* Transmitter ready DMA enable */ | 91 | #define UCR1_TDMAEN (1<<3) /* Transmitter ready DMA enable */ |
104 | #ifdef CONFIG_ARCH_MX1 | 92 | #define MX1_UCR1_UARTCLKEN (1<<2) /* UART clock enabled, mx1 only */ |
105 | #define UCR1_UARTCLKEN (1<<2) /* UART clock enabled */ | ||
106 | #endif | ||
107 | #if defined CONFIG_ARCH_MX3 || defined CONFIG_ARCH_MX2 | ||
108 | #define UCR1_UARTCLKEN (0) /* not present on mx2/mx3 */ | ||
109 | #endif | ||
110 | #define UCR1_DOZE (1<<1) /* Doze */ | 93 | #define UCR1_DOZE (1<<1) /* Doze */ |
111 | #define UCR1_UARTEN (1<<0) /* UART enabled */ | 94 | #define UCR1_UARTEN (1<<0) /* UART enabled */ |
112 | #define UCR2_ESCI (1<<15) /* Escape seq interrupt enable */ | 95 | #define UCR2_ESCI (1<<15) /* Escape seq interrupt enable */ |
@@ -132,16 +115,13 @@ | |||
132 | #define UCR3_RXDSEN (1<<6) /* Receive status interrupt enable */ | 115 | #define UCR3_RXDSEN (1<<6) /* Receive status interrupt enable */ |
133 | #define UCR3_AIRINTEN (1<<5) /* Async IR wake interrupt enable */ | 116 | #define UCR3_AIRINTEN (1<<5) /* Async IR wake interrupt enable */ |
134 | #define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */ | 117 | #define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */ |
135 | #ifdef CONFIG_ARCH_MX1 | 118 | #define MX1_UCR3_REF25 (1<<3) /* Ref freq 25 MHz, only on mx1 */ |
136 | #define UCR3_REF25 (1<<3) /* Ref freq 25 MHz, only on mx1 */ | 119 | #define MX1_UCR3_REF30 (1<<2) /* Ref Freq 30 MHz, only on mx1 */ |
137 | #define UCR3_REF30 (1<<2) /* Ref Freq 30 MHz, only on mx1 */ | 120 | #define MX2_UCR3_RXDMUXSEL (1<<2) /* RXD Muxed Input Select, on mx2/mx3 */ |
138 | #endif | ||
139 | #if defined CONFIG_ARCH_MX2 || defined CONFIG_ARCH_MX3 | ||
140 | #define UCR3_RXDMUXSEL (1<<2) /* RXD Muxed Input Select, on mx2/mx3 */ | ||
141 | #endif | ||
142 | #define UCR3_INVT (1<<1) /* Inverted Infrared transmission */ | 121 | #define UCR3_INVT (1<<1) /* Inverted Infrared transmission */ |
143 | #define UCR3_BPEN (1<<0) /* Preset registers enable */ | 122 | #define UCR3_BPEN (1<<0) /* Preset registers enable */ |
144 | #define UCR4_CTSTL_32 (32<<10) /* CTS trigger level (32 chars) */ | 123 | #define UCR4_CTSTL_SHF 10 /* CTS trigger level shift */ |
124 | #define UCR4_CTSTL_MASK 0x3F /* CTS trigger is 6 bits wide */ | ||
145 | #define UCR4_INVR (1<<9) /* Inverted infrared reception */ | 125 | #define UCR4_INVR (1<<9) /* Inverted infrared reception */ |
146 | #define UCR4_ENIRI (1<<8) /* Serial infrared interrupt enable */ | 126 | #define UCR4_ENIRI (1<<8) /* Serial infrared interrupt enable */ |
147 | #define UCR4_WKEN (1<<7) /* Wake interrupt enable */ | 127 | #define UCR4_WKEN (1<<7) /* Wake interrupt enable */ |
@@ -186,12 +166,10 @@ | |||
186 | #define UTS_SOFTRST (1<<0) /* Software reset */ | 166 | #define UTS_SOFTRST (1<<0) /* Software reset */ |
187 | 167 | ||
188 | /* We've been assigned a range on the "Low-density serial ports" major */ | 168 | /* We've been assigned a range on the "Low-density serial ports" major */ |
189 | #ifdef CONFIG_ARCH_MXC | ||
190 | #define SERIAL_IMX_MAJOR 207 | 169 | #define SERIAL_IMX_MAJOR 207 |
191 | #define MINOR_START 16 | 170 | #define MINOR_START 16 |
192 | #define DEV_NAME "ttymxc" | 171 | #define DEV_NAME "ttymxc" |
193 | #define MAX_INTERNAL_IRQ MXC_INTERNAL_IRQS | 172 | #define MAX_INTERNAL_IRQ MXC_INTERNAL_IRQS |
194 | #endif | ||
195 | 173 | ||
196 | /* | 174 | /* |
197 | * This determines how often we check the modem status signals | 175 | * This determines how often we check the modem status signals |
@@ -248,7 +226,7 @@ static void imx_mctrl_check(struct imx_port *sport) | |||
248 | if (changed & TIOCM_CTS) | 226 | if (changed & TIOCM_CTS) |
249 | uart_handle_cts_change(&sport->port, status & TIOCM_CTS); | 227 | uart_handle_cts_change(&sport->port, status & TIOCM_CTS); |
250 | 228 | ||
251 | wake_up_interruptible(&sport->port.info->delta_msr_wait); | 229 | wake_up_interruptible(&sport->port.state->port.delta_msr_wait); |
252 | } | 230 | } |
253 | 231 | ||
254 | /* | 232 | /* |
@@ -260,7 +238,7 @@ static void imx_timeout(unsigned long data) | |||
260 | struct imx_port *sport = (struct imx_port *)data; | 238 | struct imx_port *sport = (struct imx_port *)data; |
261 | unsigned long flags; | 239 | unsigned long flags; |
262 | 240 | ||
263 | if (sport->port.info) { | 241 | if (sport->port.state) { |
264 | spin_lock_irqsave(&sport->port.lock, flags); | 242 | spin_lock_irqsave(&sport->port.lock, flags); |
265 | imx_mctrl_check(sport); | 243 | imx_mctrl_check(sport); |
266 | spin_unlock_irqrestore(&sport->port.lock, flags); | 244 | spin_unlock_irqrestore(&sport->port.lock, flags); |
@@ -347,16 +325,15 @@ static void imx_enable_ms(struct uart_port *port) | |||
347 | 325 | ||
348 | static inline void imx_transmit_buffer(struct imx_port *sport) | 326 | static inline void imx_transmit_buffer(struct imx_port *sport) |
349 | { | 327 | { |
350 | struct circ_buf *xmit = &sport->port.info->xmit; | 328 | struct circ_buf *xmit = &sport->port.state->xmit; |
351 | 329 | ||
352 | while (!(readl(sport->port.membase + UTS) & UTS_TXFULL)) { | 330 | while (!uart_circ_empty(xmit) && |
331 | !(readl(sport->port.membase + UTS) & UTS_TXFULL)) { | ||
353 | /* send xmit->buf[xmit->tail] | 332 | /* send xmit->buf[xmit->tail] |
354 | * out the port here */ | 333 | * out the port here */ |
355 | writel(xmit->buf[xmit->tail], sport->port.membase + URTX0); | 334 | writel(xmit->buf[xmit->tail], sport->port.membase + URTX0); |
356 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | 335 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); |
357 | sport->port.icount.tx++; | 336 | sport->port.icount.tx++; |
358 | if (uart_circ_empty(xmit)) | ||
359 | break; | ||
360 | } | 337 | } |
361 | 338 | ||
362 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 339 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
@@ -412,7 +389,7 @@ static irqreturn_t imx_rtsint(int irq, void *dev_id) | |||
412 | 389 | ||
413 | writel(USR1_RTSD, sport->port.membase + USR1); | 390 | writel(USR1_RTSD, sport->port.membase + USR1); |
414 | uart_handle_cts_change(&sport->port, !!val); | 391 | uart_handle_cts_change(&sport->port, !!val); |
415 | wake_up_interruptible(&sport->port.info->delta_msr_wait); | 392 | wake_up_interruptible(&sport->port.state->port.delta_msr_wait); |
416 | 393 | ||
417 | spin_unlock_irqrestore(&sport->port.lock, flags); | 394 | spin_unlock_irqrestore(&sport->port.lock, flags); |
418 | return IRQ_HANDLED; | 395 | return IRQ_HANDLED; |
@@ -421,7 +398,7 @@ static irqreturn_t imx_rtsint(int irq, void *dev_id) | |||
421 | static irqreturn_t imx_txint(int irq, void *dev_id) | 398 | static irqreturn_t imx_txint(int irq, void *dev_id) |
422 | { | 399 | { |
423 | struct imx_port *sport = dev_id; | 400 | struct imx_port *sport = dev_id; |
424 | struct circ_buf *xmit = &sport->port.info->xmit; | 401 | struct circ_buf *xmit = &sport->port.state->xmit; |
425 | unsigned long flags; | 402 | unsigned long flags; |
426 | 403 | ||
427 | spin_lock_irqsave(&sport->port.lock,flags); | 404 | spin_lock_irqsave(&sport->port.lock,flags); |
@@ -451,7 +428,7 @@ static irqreturn_t imx_rxint(int irq, void *dev_id) | |||
451 | { | 428 | { |
452 | struct imx_port *sport = dev_id; | 429 | struct imx_port *sport = dev_id; |
453 | unsigned int rx,flg,ignored = 0; | 430 | unsigned int rx,flg,ignored = 0; |
454 | struct tty_struct *tty = sport->port.info->port.tty; | 431 | struct tty_struct *tty = sport->port.state->port.tty; |
455 | unsigned long flags, temp; | 432 | unsigned long flags, temp; |
456 | 433 | ||
457 | spin_lock_irqsave(&sport->port.lock,flags); | 434 | spin_lock_irqsave(&sport->port.lock,flags); |
@@ -464,7 +441,7 @@ static irqreturn_t imx_rxint(int irq, void *dev_id) | |||
464 | 441 | ||
465 | temp = readl(sport->port.membase + USR2); | 442 | temp = readl(sport->port.membase + USR2); |
466 | if (temp & USR2_BRCD) { | 443 | if (temp & USR2_BRCD) { |
467 | writel(temp | USR2_BRCD, sport->port.membase + USR2); | 444 | writel(USR2_BRCD, sport->port.membase + USR2); |
468 | if (uart_handle_break(&sport->port)) | 445 | if (uart_handle_break(&sport->port)) |
469 | continue; | 446 | continue; |
470 | } | 447 | } |
@@ -614,6 +591,9 @@ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode) | |||
614 | return 0; | 591 | return 0; |
615 | } | 592 | } |
616 | 593 | ||
594 | /* half the RX buffer size */ | ||
595 | #define CTSTL 16 | ||
596 | |||
617 | static int imx_startup(struct uart_port *port) | 597 | static int imx_startup(struct uart_port *port) |
618 | { | 598 | { |
619 | struct imx_port *sport = (struct imx_port *)port; | 599 | struct imx_port *sport = (struct imx_port *)port; |
@@ -630,6 +610,10 @@ static int imx_startup(struct uart_port *port) | |||
630 | if (USE_IRDA(sport)) | 610 | if (USE_IRDA(sport)) |
631 | temp |= UCR4_IRSC; | 611 | temp |= UCR4_IRSC; |
632 | 612 | ||
613 | /* set the trigger level for CTS */ | ||
614 | temp &= ~(UCR4_CTSTL_MASK<< UCR4_CTSTL_SHF); | ||
615 | temp |= CTSTL<< UCR4_CTSTL_SHF; | ||
616 | |||
633 | writel(temp & ~UCR4_DREN, sport->port.membase + UCR4); | 617 | writel(temp & ~UCR4_DREN, sport->port.membase + UCR4); |
634 | 618 | ||
635 | if (USE_IRDA(sport)) { | 619 | if (USE_IRDA(sport)) { |
@@ -706,11 +690,11 @@ static int imx_startup(struct uart_port *port) | |||
706 | } | 690 | } |
707 | } | 691 | } |
708 | 692 | ||
709 | #if defined CONFIG_ARCH_MX2 || defined CONFIG_ARCH_MX3 | 693 | if (!cpu_is_mx1()) { |
710 | temp = readl(sport->port.membase + UCR3); | 694 | temp = readl(sport->port.membase + UCR3); |
711 | temp |= UCR3_RXDMUXSEL; | 695 | temp |= MX2_UCR3_RXDMUXSEL; |
712 | writel(temp, sport->port.membase + UCR3); | 696 | writel(temp, sport->port.membase + UCR3); |
713 | #endif | 697 | } |
714 | 698 | ||
715 | if (USE_IRDA(sport)) { | 699 | if (USE_IRDA(sport)) { |
716 | temp = readl(sport->port.membase + UCR4); | 700 | temp = readl(sport->port.membase + UCR4); |
@@ -924,13 +908,11 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, | |||
924 | rational_best_approximation(16 * div * baud, sport->port.uartclk, | 908 | rational_best_approximation(16 * div * baud, sport->port.uartclk, |
925 | 1 << 16, 1 << 16, &num, &denom); | 909 | 1 << 16, 1 << 16, &num, &denom); |
926 | 910 | ||
927 | if (port->info && port->info->port.tty) { | 911 | tdiv64 = sport->port.uartclk; |
928 | tdiv64 = sport->port.uartclk; | 912 | tdiv64 *= num; |
929 | tdiv64 *= num; | 913 | do_div(tdiv64, denom * 16 * div); |
930 | do_div(tdiv64, denom * 16 * div); | 914 | tty_termios_encode_baud_rate(termios, |
931 | tty_encode_baud_rate(sport->port.info->port.tty, | ||
932 | (speed_t)tdiv64, (speed_t)tdiv64); | 915 | (speed_t)tdiv64, (speed_t)tdiv64); |
933 | } | ||
934 | 916 | ||
935 | num -= 1; | 917 | num -= 1; |
936 | denom -= 1; | 918 | denom -= 1; |
@@ -942,9 +924,9 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, | |||
942 | writel(num, sport->port.membase + UBIR); | 924 | writel(num, sport->port.membase + UBIR); |
943 | writel(denom, sport->port.membase + UBMR); | 925 | writel(denom, sport->port.membase + UBMR); |
944 | 926 | ||
945 | #ifdef ONEMS | 927 | if (!cpu_is_mx1()) |
946 | writel(sport->port.uartclk / div / 1000, sport->port.membase + ONEMS); | 928 | writel(sport->port.uartclk / div / 1000, |
947 | #endif | 929 | sport->port.membase + MX2_ONEMS); |
948 | 930 | ||
949 | writel(old_ucr1, sport->port.membase + UCR1); | 931 | writel(old_ucr1, sport->port.membase + UCR1); |
950 | 932 | ||
@@ -1074,17 +1056,20 @@ static void | |||
1074 | imx_console_write(struct console *co, const char *s, unsigned int count) | 1056 | imx_console_write(struct console *co, const char *s, unsigned int count) |
1075 | { | 1057 | { |
1076 | struct imx_port *sport = imx_ports[co->index]; | 1058 | struct imx_port *sport = imx_ports[co->index]; |
1077 | unsigned int old_ucr1, old_ucr2; | 1059 | unsigned int old_ucr1, old_ucr2, ucr1; |
1078 | 1060 | ||
1079 | /* | 1061 | /* |
1080 | * First, save UCR1/2 and then disable interrupts | 1062 | * First, save UCR1/2 and then disable interrupts |
1081 | */ | 1063 | */ |
1082 | old_ucr1 = readl(sport->port.membase + UCR1); | 1064 | ucr1 = old_ucr1 = readl(sport->port.membase + UCR1); |
1083 | old_ucr2 = readl(sport->port.membase + UCR2); | 1065 | old_ucr2 = readl(sport->port.membase + UCR2); |
1084 | 1066 | ||
1085 | writel((old_ucr1 | UCR1_UARTCLKEN | UCR1_UARTEN) & | 1067 | if (cpu_is_mx1()) |
1086 | ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN), | 1068 | ucr1 |= MX1_UCR1_UARTCLKEN; |
1087 | sport->port.membase + UCR1); | 1069 | ucr1 |= UCR1_UARTEN; |
1070 | ucr1 &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN); | ||
1071 | |||
1072 | writel(ucr1, sport->port.membase + UCR1); | ||
1088 | 1073 | ||
1089 | writel(old_ucr2 | UCR2_TXEN, sport->port.membase + UCR2); | 1074 | writel(old_ucr2 | UCR2_TXEN, sport->port.membase + UCR2); |
1090 | 1075 | ||
@@ -1109,7 +1094,7 @@ imx_console_get_options(struct imx_port *sport, int *baud, | |||
1109 | int *parity, int *bits) | 1094 | int *parity, int *bits) |
1110 | { | 1095 | { |
1111 | 1096 | ||
1112 | if ( readl(sport->port.membase + UCR1) | UCR1_UARTEN ) { | 1097 | if (readl(sport->port.membase + UCR1) & UCR1_UARTEN) { |
1113 | /* ok, the port was enabled */ | 1098 | /* ok, the port was enabled */ |
1114 | unsigned int ucr2, ubir,ubmr, uartclk; | 1099 | unsigned int ucr2, ubir,ubmr, uartclk; |
1115 | unsigned int baud_raw; | 1100 | unsigned int baud_raw; |
@@ -1300,7 +1285,7 @@ static int serial_imx_probe(struct platform_device *pdev) | |||
1300 | sport->use_irda = 1; | 1285 | sport->use_irda = 1; |
1301 | #endif | 1286 | #endif |
1302 | 1287 | ||
1303 | if (pdata->init) { | 1288 | if (pdata && pdata->init) { |
1304 | ret = pdata->init(pdev); | 1289 | ret = pdata->init(pdev); |
1305 | if (ret) | 1290 | if (ret) |
1306 | goto clkput; | 1291 | goto clkput; |
@@ -1313,7 +1298,7 @@ static int serial_imx_probe(struct platform_device *pdev) | |||
1313 | 1298 | ||
1314 | return 0; | 1299 | return 0; |
1315 | deinit: | 1300 | deinit: |
1316 | if (pdata->exit) | 1301 | if (pdata && pdata->exit) |
1317 | pdata->exit(pdev); | 1302 | pdata->exit(pdev); |
1318 | clkput: | 1303 | clkput: |
1319 | clk_put(sport->clk); | 1304 | clk_put(sport->clk); |
@@ -1342,7 +1327,7 @@ static int serial_imx_remove(struct platform_device *pdev) | |||
1342 | 1327 | ||
1343 | clk_disable(sport->clk); | 1328 | clk_disable(sport->clk); |
1344 | 1329 | ||
1345 | if (pdata->exit) | 1330 | if (pdata && pdata->exit) |
1346 | pdata->exit(pdev); | 1331 | pdata->exit(pdev); |
1347 | 1332 | ||
1348 | iounmap(sport->port.membase); | 1333 | iounmap(sport->port.membase); |
diff --git a/drivers/serial/ioc3_serial.c b/drivers/serial/ioc3_serial.c index ae3699d77dd0..ee43efc7bdcc 100644 --- a/drivers/serial/ioc3_serial.c +++ b/drivers/serial/ioc3_serial.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/pci.h> | 20 | #include <linux/pci.h> |
21 | #include <linux/serial_core.h> | 21 | #include <linux/serial_core.h> |
22 | #include <linux/ioc3.h> | 22 | #include <linux/ioc3.h> |
23 | #include <linux/slab.h> | ||
23 | 24 | ||
24 | /* | 25 | /* |
25 | * Interesting things about the ioc3 | 26 | * Interesting things about the ioc3 |
@@ -897,25 +898,25 @@ static void transmit_chars(struct uart_port *the_port) | |||
897 | char *start; | 898 | char *start; |
898 | struct tty_struct *tty; | 899 | struct tty_struct *tty; |
899 | struct ioc3_port *port = get_ioc3_port(the_port); | 900 | struct ioc3_port *port = get_ioc3_port(the_port); |
900 | struct uart_info *info; | 901 | struct uart_state *state; |
901 | 902 | ||
902 | if (!the_port) | 903 | if (!the_port) |
903 | return; | 904 | return; |
904 | if (!port) | 905 | if (!port) |
905 | return; | 906 | return; |
906 | 907 | ||
907 | info = the_port->info; | 908 | state = the_port->state; |
908 | tty = info->port.tty; | 909 | tty = state->port.tty; |
909 | 910 | ||
910 | if (uart_circ_empty(&info->xmit) || uart_tx_stopped(the_port)) { | 911 | if (uart_circ_empty(&state->xmit) || uart_tx_stopped(the_port)) { |
911 | /* Nothing to do or hw stopped */ | 912 | /* Nothing to do or hw stopped */ |
912 | set_notification(port, N_ALL_OUTPUT, 0); | 913 | set_notification(port, N_ALL_OUTPUT, 0); |
913 | return; | 914 | return; |
914 | } | 915 | } |
915 | 916 | ||
916 | head = info->xmit.head; | 917 | head = state->xmit.head; |
917 | tail = info->xmit.tail; | 918 | tail = state->xmit.tail; |
918 | start = (char *)&info->xmit.buf[tail]; | 919 | start = (char *)&state->xmit.buf[tail]; |
919 | 920 | ||
920 | /* write out all the data or until the end of the buffer */ | 921 | /* write out all the data or until the end of the buffer */ |
921 | xmit_count = (head < tail) ? (UART_XMIT_SIZE - tail) : (head - tail); | 922 | xmit_count = (head < tail) ? (UART_XMIT_SIZE - tail) : (head - tail); |
@@ -928,14 +929,14 @@ static void transmit_chars(struct uart_port *the_port) | |||
928 | /* advance the pointers */ | 929 | /* advance the pointers */ |
929 | tail += result; | 930 | tail += result; |
930 | tail &= UART_XMIT_SIZE - 1; | 931 | tail &= UART_XMIT_SIZE - 1; |
931 | info->xmit.tail = tail; | 932 | state->xmit.tail = tail; |
932 | start = (char *)&info->xmit.buf[tail]; | 933 | start = (char *)&state->xmit.buf[tail]; |
933 | } | 934 | } |
934 | } | 935 | } |
935 | if (uart_circ_chars_pending(&info->xmit) < WAKEUP_CHARS) | 936 | if (uart_circ_chars_pending(&state->xmit) < WAKEUP_CHARS) |
936 | uart_write_wakeup(the_port); | 937 | uart_write_wakeup(the_port); |
937 | 938 | ||
938 | if (uart_circ_empty(&info->xmit)) { | 939 | if (uart_circ_empty(&state->xmit)) { |
939 | set_notification(port, N_OUTPUT_LOWAT, 0); | 940 | set_notification(port, N_OUTPUT_LOWAT, 0); |
940 | } else { | 941 | } else { |
941 | set_notification(port, N_OUTPUT_LOWAT, 1); | 942 | set_notification(port, N_OUTPUT_LOWAT, 1); |
@@ -953,12 +954,13 @@ ioc3_change_speed(struct uart_port *the_port, | |||
953 | struct ktermios *new_termios, struct ktermios *old_termios) | 954 | struct ktermios *new_termios, struct ktermios *old_termios) |
954 | { | 955 | { |
955 | struct ioc3_port *port = get_ioc3_port(the_port); | 956 | struct ioc3_port *port = get_ioc3_port(the_port); |
956 | unsigned int cflag; | 957 | unsigned int cflag, iflag; |
957 | int baud; | 958 | int baud; |
958 | int new_parity = 0, new_parity_enable = 0, new_stop = 0, new_data = 8; | 959 | int new_parity = 0, new_parity_enable = 0, new_stop = 0, new_data = 8; |
959 | struct uart_info *info = the_port->info; | 960 | struct uart_state *state = the_port->state; |
960 | 961 | ||
961 | cflag = new_termios->c_cflag; | 962 | cflag = new_termios->c_cflag; |
963 | iflag = new_termios->c_iflag; | ||
962 | 964 | ||
963 | switch (cflag & CSIZE) { | 965 | switch (cflag & CSIZE) { |
964 | case CS5: | 966 | case CS5: |
@@ -997,14 +999,14 @@ ioc3_change_speed(struct uart_port *the_port, | |||
997 | 999 | ||
998 | the_port->ignore_status_mask = N_ALL_INPUT; | 1000 | the_port->ignore_status_mask = N_ALL_INPUT; |
999 | 1001 | ||
1000 | info->port.tty->low_latency = 1; | 1002 | state->port.tty->low_latency = 1; |
1001 | 1003 | ||
1002 | if (I_IGNPAR(info->port.tty)) | 1004 | if (iflag & IGNPAR) |
1003 | the_port->ignore_status_mask &= ~(N_PARITY_ERROR | 1005 | the_port->ignore_status_mask &= ~(N_PARITY_ERROR |
1004 | | N_FRAMING_ERROR); | 1006 | | N_FRAMING_ERROR); |
1005 | if (I_IGNBRK(info->port.tty)) { | 1007 | if (iflag & IGNBRK) { |
1006 | the_port->ignore_status_mask &= ~N_BREAK; | 1008 | the_port->ignore_status_mask &= ~N_BREAK; |
1007 | if (I_IGNPAR(info->port.tty)) | 1009 | if (iflag & IGNPAR) |
1008 | the_port->ignore_status_mask &= ~N_OVERRUN_ERROR; | 1010 | the_port->ignore_status_mask &= ~N_OVERRUN_ERROR; |
1009 | } | 1011 | } |
1010 | if (!(cflag & CREAD)) { | 1012 | if (!(cflag & CREAD)) { |
@@ -1286,8 +1288,8 @@ static inline int do_read(struct uart_port *the_port, char *buf, int len) | |||
1286 | uart_handle_dcd_change | 1288 | uart_handle_dcd_change |
1287 | (port->ip_port, 0); | 1289 | (port->ip_port, 0); |
1288 | wake_up_interruptible | 1290 | wake_up_interruptible |
1289 | (&the_port->info-> | 1291 | (&the_port->state-> |
1290 | delta_msr_wait); | 1292 | port.delta_msr_wait); |
1291 | } | 1293 | } |
1292 | 1294 | ||
1293 | /* If we had any data to return, we | 1295 | /* If we had any data to return, we |
@@ -1392,27 +1394,26 @@ static int receive_chars(struct uart_port *the_port) | |||
1392 | struct tty_struct *tty; | 1394 | struct tty_struct *tty; |
1393 | unsigned char ch[MAX_CHARS]; | 1395 | unsigned char ch[MAX_CHARS]; |
1394 | int read_count = 0, read_room, flip = 0; | 1396 | int read_count = 0, read_room, flip = 0; |
1395 | struct uart_info *info = the_port->info; | 1397 | struct uart_state *state = the_port->state; |
1396 | struct ioc3_port *port = get_ioc3_port(the_port); | 1398 | struct ioc3_port *port = get_ioc3_port(the_port); |
1397 | unsigned long pflags; | 1399 | unsigned long pflags; |
1398 | 1400 | ||
1399 | /* Make sure all the pointers are "good" ones */ | 1401 | /* Make sure all the pointers are "good" ones */ |
1400 | if (!info) | 1402 | if (!state) |
1401 | return 0; | 1403 | return 0; |
1402 | if (!info->port.tty) | 1404 | if (!state->port.tty) |
1403 | return 0; | 1405 | return 0; |
1404 | 1406 | ||
1405 | if (!(port->ip_flags & INPUT_ENABLE)) | 1407 | if (!(port->ip_flags & INPUT_ENABLE)) |
1406 | return 0; | 1408 | return 0; |
1407 | 1409 | ||
1408 | spin_lock_irqsave(&the_port->lock, pflags); | 1410 | spin_lock_irqsave(&the_port->lock, pflags); |
1409 | tty = info->port.tty; | 1411 | tty = state->port.tty; |
1410 | 1412 | ||
1411 | read_count = do_read(the_port, ch, MAX_CHARS); | 1413 | read_count = do_read(the_port, ch, MAX_CHARS); |
1412 | if (read_count > 0) { | 1414 | if (read_count > 0) { |
1413 | flip = 1; | 1415 | flip = 1; |
1414 | read_room = tty_buffer_request_room(tty, read_count); | 1416 | read_room = tty_insert_flip_string(tty, ch, read_count); |
1415 | tty_insert_flip_string(tty, ch, read_room); | ||
1416 | the_port->icount.rx += read_count; | 1417 | the_port->icount.rx += read_count; |
1417 | } | 1418 | } |
1418 | spin_unlock_irqrestore(&the_port->lock, pflags); | 1419 | spin_unlock_irqrestore(&the_port->lock, pflags); |
@@ -1491,7 +1492,7 @@ ioc3uart_intr_one(struct ioc3_submodule *is, | |||
1491 | uart_handle_dcd_change(the_port, | 1492 | uart_handle_dcd_change(the_port, |
1492 | shadow & SHADOW_DCD); | 1493 | shadow & SHADOW_DCD); |
1493 | wake_up_interruptible | 1494 | wake_up_interruptible |
1494 | (&the_port->info->delta_msr_wait); | 1495 | (&the_port->state->port.delta_msr_wait); |
1495 | } else if ((port->ip_notify & N_DDCD) | 1496 | } else if ((port->ip_notify & N_DDCD) |
1496 | && !(shadow & SHADOW_DCD)) { | 1497 | && !(shadow & SHADOW_DCD)) { |
1497 | /* Flag delta DCD/no DCD */ | 1498 | /* Flag delta DCD/no DCD */ |
@@ -1511,7 +1512,7 @@ ioc3uart_intr_one(struct ioc3_submodule *is, | |||
1511 | uart_handle_cts_change(the_port, shadow | 1512 | uart_handle_cts_change(the_port, shadow |
1512 | & SHADOW_CTS); | 1513 | & SHADOW_CTS); |
1513 | wake_up_interruptible | 1514 | wake_up_interruptible |
1514 | (&the_port->info->delta_msr_wait); | 1515 | (&the_port->state->port.delta_msr_wait); |
1515 | } | 1516 | } |
1516 | } | 1517 | } |
1517 | 1518 | ||
@@ -1721,14 +1722,14 @@ static void ic3_shutdown(struct uart_port *the_port) | |||
1721 | { | 1722 | { |
1722 | unsigned long port_flags; | 1723 | unsigned long port_flags; |
1723 | struct ioc3_port *port; | 1724 | struct ioc3_port *port; |
1724 | struct uart_info *info; | 1725 | struct uart_state *state; |
1725 | 1726 | ||
1726 | port = get_ioc3_port(the_port); | 1727 | port = get_ioc3_port(the_port); |
1727 | if (!port) | 1728 | if (!port) |
1728 | return; | 1729 | return; |
1729 | 1730 | ||
1730 | info = the_port->info; | 1731 | state = the_port->state; |
1731 | wake_up_interruptible(&info->delta_msr_wait); | 1732 | wake_up_interruptible(&state->port.delta_msr_wait); |
1732 | 1733 | ||
1733 | spin_lock_irqsave(&the_port->lock, port_flags); | 1734 | spin_lock_irqsave(&the_port->lock, port_flags); |
1734 | set_notification(port, N_ALL, 0); | 1735 | set_notification(port, N_ALL, 0); |
@@ -2016,6 +2017,7 @@ ioc3uart_probe(struct ioc3_submodule *is, struct ioc3_driver_data *idd) | |||
2016 | struct ioc3_port *port; | 2017 | struct ioc3_port *port; |
2017 | struct ioc3_port *ports[PORTS_PER_CARD]; | 2018 | struct ioc3_port *ports[PORTS_PER_CARD]; |
2018 | int phys_port; | 2019 | int phys_port; |
2020 | int cnt; | ||
2019 | 2021 | ||
2020 | DPRINT_CONFIG(("%s (0x%p, 0x%p)\n", __func__, is, idd)); | 2022 | DPRINT_CONFIG(("%s (0x%p, 0x%p)\n", __func__, is, idd)); |
2021 | 2023 | ||
@@ -2043,6 +2045,7 @@ ioc3uart_probe(struct ioc3_submodule *is, struct ioc3_driver_data *idd) | |||
2043 | if (!port) { | 2045 | if (!port) { |
2044 | printk(KERN_WARNING | 2046 | printk(KERN_WARNING |
2045 | "IOC3 serial memory not available for port\n"); | 2047 | "IOC3 serial memory not available for port\n"); |
2048 | ret = -ENOMEM; | ||
2046 | goto out4; | 2049 | goto out4; |
2047 | } | 2050 | } |
2048 | spin_lock_init(&port->ip_lock); | 2051 | spin_lock_init(&port->ip_lock); |
@@ -2145,6 +2148,9 @@ ioc3uart_probe(struct ioc3_submodule *is, struct ioc3_driver_data *idd) | |||
2145 | 2148 | ||
2146 | /* error exits that give back resources */ | 2149 | /* error exits that give back resources */ |
2147 | out4: | 2150 | out4: |
2151 | for (cnt = 0; cnt < phys_port; cnt++) | ||
2152 | kfree(ports[cnt]); | ||
2153 | |||
2148 | kfree(card_ptr); | 2154 | kfree(card_ptr); |
2149 | return ret; | 2155 | return ret; |
2150 | } | 2156 | } |
@@ -2162,7 +2168,7 @@ static struct ioc3_submodule ioc3uart_ops = { | |||
2162 | /** | 2168 | /** |
2163 | * ioc3_detect - module init called, | 2169 | * ioc3_detect - module init called, |
2164 | */ | 2170 | */ |
2165 | static int __devinit ioc3uart_init(void) | 2171 | static int __init ioc3uart_init(void) |
2166 | { | 2172 | { |
2167 | int ret; | 2173 | int ret; |
2168 | 2174 | ||
@@ -2179,7 +2185,7 @@ static int __devinit ioc3uart_init(void) | |||
2179 | return ret; | 2185 | return ret; |
2180 | } | 2186 | } |
2181 | 2187 | ||
2182 | static void __devexit ioc3uart_exit(void) | 2188 | static void __exit ioc3uart_exit(void) |
2183 | { | 2189 | { |
2184 | ioc3_unregister_submodule(&ioc3uart_ops); | 2190 | ioc3_unregister_submodule(&ioc3uart_ops); |
2185 | uart_unregister_driver(&ioc3_uart); | 2191 | uart_unregister_driver(&ioc3_uart); |
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c index 6bab63cd5b29..fcfe82653ac8 100644 --- a/drivers/serial/ioc4_serial.c +++ b/drivers/serial/ioc4_serial.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/pci.h> | 22 | #include <linux/pci.h> |
23 | #include <linux/ioc4.h> | 23 | #include <linux/ioc4.h> |
24 | #include <linux/serial_core.h> | 24 | #include <linux/serial_core.h> |
25 | #include <linux/slab.h> | ||
25 | 26 | ||
26 | /* | 27 | /* |
27 | * interesting things about the ioc4 | 28 | * interesting things about the ioc4 |
@@ -930,7 +931,7 @@ static void handle_dma_error_intr(void *arg, uint32_t other_ir) | |||
930 | 931 | ||
931 | if (readl(&port->ip_mem->pci_err_addr_l.raw) & IOC4_PCI_ERR_ADDR_VLD) { | 932 | if (readl(&port->ip_mem->pci_err_addr_l.raw) & IOC4_PCI_ERR_ADDR_VLD) { |
932 | printk(KERN_ERR | 933 | printk(KERN_ERR |
933 | "PCI error address is 0x%lx, " | 934 | "PCI error address is 0x%llx, " |
934 | "master is serial port %c %s\n", | 935 | "master is serial port %c %s\n", |
935 | (((uint64_t)readl(&port->ip_mem->pci_err_addr_h) | 936 | (((uint64_t)readl(&port->ip_mem->pci_err_addr_h) |
936 | << 32) | 937 | << 32) |
@@ -1627,25 +1628,25 @@ static void transmit_chars(struct uart_port *the_port) | |||
1627 | char *start; | 1628 | char *start; |
1628 | struct tty_struct *tty; | 1629 | struct tty_struct *tty; |
1629 | struct ioc4_port *port = get_ioc4_port(the_port, 0); | 1630 | struct ioc4_port *port = get_ioc4_port(the_port, 0); |
1630 | struct uart_info *info; | 1631 | struct uart_state *state; |
1631 | 1632 | ||
1632 | if (!the_port) | 1633 | if (!the_port) |
1633 | return; | 1634 | return; |
1634 | if (!port) | 1635 | if (!port) |
1635 | return; | 1636 | return; |
1636 | 1637 | ||
1637 | info = the_port->info; | 1638 | state = the_port->state; |
1638 | tty = info->port.tty; | 1639 | tty = state->port.tty; |
1639 | 1640 | ||
1640 | if (uart_circ_empty(&info->xmit) || uart_tx_stopped(the_port)) { | 1641 | if (uart_circ_empty(&state->xmit) || uart_tx_stopped(the_port)) { |
1641 | /* Nothing to do or hw stopped */ | 1642 | /* Nothing to do or hw stopped */ |
1642 | set_notification(port, N_ALL_OUTPUT, 0); | 1643 | set_notification(port, N_ALL_OUTPUT, 0); |
1643 | return; | 1644 | return; |
1644 | } | 1645 | } |
1645 | 1646 | ||
1646 | head = info->xmit.head; | 1647 | head = state->xmit.head; |
1647 | tail = info->xmit.tail; | 1648 | tail = state->xmit.tail; |
1648 | start = (char *)&info->xmit.buf[tail]; | 1649 | start = (char *)&state->xmit.buf[tail]; |
1649 | 1650 | ||
1650 | /* write out all the data or until the end of the buffer */ | 1651 | /* write out all the data or until the end of the buffer */ |
1651 | xmit_count = (head < tail) ? (UART_XMIT_SIZE - tail) : (head - tail); | 1652 | xmit_count = (head < tail) ? (UART_XMIT_SIZE - tail) : (head - tail); |
@@ -1658,14 +1659,14 @@ static void transmit_chars(struct uart_port *the_port) | |||
1658 | /* advance the pointers */ | 1659 | /* advance the pointers */ |
1659 | tail += result; | 1660 | tail += result; |
1660 | tail &= UART_XMIT_SIZE - 1; | 1661 | tail &= UART_XMIT_SIZE - 1; |
1661 | info->xmit.tail = tail; | 1662 | state->xmit.tail = tail; |
1662 | start = (char *)&info->xmit.buf[tail]; | 1663 | start = (char *)&state->xmit.buf[tail]; |
1663 | } | 1664 | } |
1664 | } | 1665 | } |
1665 | if (uart_circ_chars_pending(&info->xmit) < WAKEUP_CHARS) | 1666 | if (uart_circ_chars_pending(&state->xmit) < WAKEUP_CHARS) |
1666 | uart_write_wakeup(the_port); | 1667 | uart_write_wakeup(the_port); |
1667 | 1668 | ||
1668 | if (uart_circ_empty(&info->xmit)) { | 1669 | if (uart_circ_empty(&state->xmit)) { |
1669 | set_notification(port, N_OUTPUT_LOWAT, 0); | 1670 | set_notification(port, N_OUTPUT_LOWAT, 0); |
1670 | } else { | 1671 | } else { |
1671 | set_notification(port, N_OUTPUT_LOWAT, 1); | 1672 | set_notification(port, N_OUTPUT_LOWAT, 1); |
@@ -1684,11 +1685,12 @@ ioc4_change_speed(struct uart_port *the_port, | |||
1684 | { | 1685 | { |
1685 | struct ioc4_port *port = get_ioc4_port(the_port, 0); | 1686 | struct ioc4_port *port = get_ioc4_port(the_port, 0); |
1686 | int baud, bits; | 1687 | int baud, bits; |
1687 | unsigned cflag; | 1688 | unsigned cflag, iflag; |
1688 | int new_parity = 0, new_parity_enable = 0, new_stop = 0, new_data = 8; | 1689 | int new_parity = 0, new_parity_enable = 0, new_stop = 0, new_data = 8; |
1689 | struct uart_info *info = the_port->info; | 1690 | struct uart_state *state = the_port->state; |
1690 | 1691 | ||
1691 | cflag = new_termios->c_cflag; | 1692 | cflag = new_termios->c_cflag; |
1693 | iflag = new_termios->c_iflag; | ||
1692 | 1694 | ||
1693 | switch (cflag & CSIZE) { | 1695 | switch (cflag & CSIZE) { |
1694 | case CS5: | 1696 | case CS5: |
@@ -1738,14 +1740,14 @@ ioc4_change_speed(struct uart_port *the_port, | |||
1738 | 1740 | ||
1739 | the_port->ignore_status_mask = N_ALL_INPUT; | 1741 | the_port->ignore_status_mask = N_ALL_INPUT; |
1740 | 1742 | ||
1741 | info->port.tty->low_latency = 1; | 1743 | state->port.tty->low_latency = 1; |
1742 | 1744 | ||
1743 | if (I_IGNPAR(info->port.tty)) | 1745 | if (iflag & IGNPAR) |
1744 | the_port->ignore_status_mask &= ~(N_PARITY_ERROR | 1746 | the_port->ignore_status_mask &= ~(N_PARITY_ERROR |
1745 | | N_FRAMING_ERROR); | 1747 | | N_FRAMING_ERROR); |
1746 | if (I_IGNBRK(info->port.tty)) { | 1748 | if (iflag & IGNBRK) { |
1747 | the_port->ignore_status_mask &= ~N_BREAK; | 1749 | the_port->ignore_status_mask &= ~N_BREAK; |
1748 | if (I_IGNPAR(info->port.tty)) | 1750 | if (iflag & IGNPAR) |
1749 | the_port->ignore_status_mask &= ~N_OVERRUN_ERROR; | 1751 | the_port->ignore_status_mask &= ~N_OVERRUN_ERROR; |
1750 | } | 1752 | } |
1751 | if (!(cflag & CREAD)) { | 1753 | if (!(cflag & CREAD)) { |
@@ -1784,7 +1786,7 @@ ioc4_change_speed(struct uart_port *the_port, | |||
1784 | static inline int ic4_startup_local(struct uart_port *the_port) | 1786 | static inline int ic4_startup_local(struct uart_port *the_port) |
1785 | { | 1787 | { |
1786 | struct ioc4_port *port; | 1788 | struct ioc4_port *port; |
1787 | struct uart_info *info; | 1789 | struct uart_state *state; |
1788 | 1790 | ||
1789 | if (!the_port) | 1791 | if (!the_port) |
1790 | return -1; | 1792 | return -1; |
@@ -1793,7 +1795,7 @@ static inline int ic4_startup_local(struct uart_port *the_port) | |||
1793 | if (!port) | 1795 | if (!port) |
1794 | return -1; | 1796 | return -1; |
1795 | 1797 | ||
1796 | info = the_port->info; | 1798 | state = the_port->state; |
1797 | 1799 | ||
1798 | local_open(port); | 1800 | local_open(port); |
1799 | 1801 | ||
@@ -1801,7 +1803,7 @@ static inline int ic4_startup_local(struct uart_port *the_port) | |||
1801 | ioc4_set_proto(port, the_port->mapbase); | 1803 | ioc4_set_proto(port, the_port->mapbase); |
1802 | 1804 | ||
1803 | /* set the speed of the serial port */ | 1805 | /* set the speed of the serial port */ |
1804 | ioc4_change_speed(the_port, info->port.tty->termios, | 1806 | ioc4_change_speed(the_port, state->port.tty->termios, |
1805 | (struct ktermios *)0); | 1807 | (struct ktermios *)0); |
1806 | 1808 | ||
1807 | return 0; | 1809 | return 0; |
@@ -1882,7 +1884,7 @@ static void handle_intr(void *arg, uint32_t sio_ir) | |||
1882 | the_port = port->ip_port; | 1884 | the_port = port->ip_port; |
1883 | the_port->icount.dcd = 1; | 1885 | the_port->icount.dcd = 1; |
1884 | wake_up_interruptible | 1886 | wake_up_interruptible |
1885 | (&the_port-> info->delta_msr_wait); | 1887 | (&the_port->state->port.delta_msr_wait); |
1886 | } else if ((port->ip_notify & N_DDCD) | 1888 | } else if ((port->ip_notify & N_DDCD) |
1887 | && !(shadow & IOC4_SHADOW_DCD)) { | 1889 | && !(shadow & IOC4_SHADOW_DCD)) { |
1888 | /* Flag delta DCD/no DCD */ | 1890 | /* Flag delta DCD/no DCD */ |
@@ -1904,7 +1906,7 @@ static void handle_intr(void *arg, uint32_t sio_ir) | |||
1904 | the_port->icount.cts = | 1906 | the_port->icount.cts = |
1905 | (shadow & IOC4_SHADOW_CTS) ? 1 : 0; | 1907 | (shadow & IOC4_SHADOW_CTS) ? 1 : 0; |
1906 | wake_up_interruptible | 1908 | wake_up_interruptible |
1907 | (&the_port->info->delta_msr_wait); | 1909 | (&the_port->state->port.delta_msr_wait); |
1908 | } | 1910 | } |
1909 | } | 1911 | } |
1910 | 1912 | ||
@@ -2236,8 +2238,8 @@ static inline int do_read(struct uart_port *the_port, unsigned char *buf, | |||
2236 | && port->ip_port) { | 2238 | && port->ip_port) { |
2237 | the_port->icount.dcd = 0; | 2239 | the_port->icount.dcd = 0; |
2238 | wake_up_interruptible | 2240 | wake_up_interruptible |
2239 | (&the_port->info-> | 2241 | (&the_port->state-> |
2240 | delta_msr_wait); | 2242 | port.delta_msr_wait); |
2241 | } | 2243 | } |
2242 | 2244 | ||
2243 | /* If we had any data to return, we | 2245 | /* If we had any data to return, we |
@@ -2341,17 +2343,17 @@ static void receive_chars(struct uart_port *the_port) | |||
2341 | unsigned char ch[IOC4_MAX_CHARS]; | 2343 | unsigned char ch[IOC4_MAX_CHARS]; |
2342 | int read_count, request_count = IOC4_MAX_CHARS; | 2344 | int read_count, request_count = IOC4_MAX_CHARS; |
2343 | struct uart_icount *icount; | 2345 | struct uart_icount *icount; |
2344 | struct uart_info *info = the_port->info; | 2346 | struct uart_state *state = the_port->state; |
2345 | unsigned long pflags; | 2347 | unsigned long pflags; |
2346 | 2348 | ||
2347 | /* Make sure all the pointers are "good" ones */ | 2349 | /* Make sure all the pointers are "good" ones */ |
2348 | if (!info) | 2350 | if (!state) |
2349 | return; | 2351 | return; |
2350 | if (!info->port.tty) | 2352 | if (!state->port.tty) |
2351 | return; | 2353 | return; |
2352 | 2354 | ||
2353 | spin_lock_irqsave(&the_port->lock, pflags); | 2355 | spin_lock_irqsave(&the_port->lock, pflags); |
2354 | tty = info->port.tty; | 2356 | tty = state->port.tty; |
2355 | 2357 | ||
2356 | request_count = tty_buffer_request_room(tty, IOC4_MAX_CHARS); | 2358 | request_count = tty_buffer_request_room(tty, IOC4_MAX_CHARS); |
2357 | 2359 | ||
@@ -2430,19 +2432,19 @@ static void ic4_shutdown(struct uart_port *the_port) | |||
2430 | { | 2432 | { |
2431 | unsigned long port_flags; | 2433 | unsigned long port_flags; |
2432 | struct ioc4_port *port; | 2434 | struct ioc4_port *port; |
2433 | struct uart_info *info; | 2435 | struct uart_state *state; |
2434 | 2436 | ||
2435 | port = get_ioc4_port(the_port, 0); | 2437 | port = get_ioc4_port(the_port, 0); |
2436 | if (!port) | 2438 | if (!port) |
2437 | return; | 2439 | return; |
2438 | 2440 | ||
2439 | info = the_port->info; | 2441 | state = the_port->state; |
2440 | port->ip_port = NULL; | 2442 | port->ip_port = NULL; |
2441 | 2443 | ||
2442 | wake_up_interruptible(&info->delta_msr_wait); | 2444 | wake_up_interruptible(&state->port.delta_msr_wait); |
2443 | 2445 | ||
2444 | if (info->port.tty) | 2446 | if (state->port.tty) |
2445 | set_bit(TTY_IO_ERROR, &info->port.tty->flags); | 2447 | set_bit(TTY_IO_ERROR, &state->port.tty->flags); |
2446 | 2448 | ||
2447 | spin_lock_irqsave(&the_port->lock, port_flags); | 2449 | spin_lock_irqsave(&the_port->lock, port_flags); |
2448 | set_notification(port, N_ALL, 0); | 2450 | set_notification(port, N_ALL, 0); |
@@ -2538,7 +2540,7 @@ static int ic4_startup(struct uart_port *the_port) | |||
2538 | int retval; | 2540 | int retval; |
2539 | struct ioc4_port *port; | 2541 | struct ioc4_port *port; |
2540 | struct ioc4_control *control; | 2542 | struct ioc4_control *control; |
2541 | struct uart_info *info; | 2543 | struct uart_state *state; |
2542 | unsigned long port_flags; | 2544 | unsigned long port_flags; |
2543 | 2545 | ||
2544 | if (!the_port) | 2546 | if (!the_port) |
@@ -2546,7 +2548,7 @@ static int ic4_startup(struct uart_port *the_port) | |||
2546 | port = get_ioc4_port(the_port, 1); | 2548 | port = get_ioc4_port(the_port, 1); |
2547 | if (!port) | 2549 | if (!port) |
2548 | return -ENODEV; | 2550 | return -ENODEV; |
2549 | info = the_port->info; | 2551 | state = the_port->state; |
2550 | 2552 | ||
2551 | control = port->ip_control; | 2553 | control = port->ip_control; |
2552 | if (!control) { | 2554 | if (!control) { |
@@ -2904,7 +2906,7 @@ static struct ioc4_submodule ioc4_serial_submodule = { | |||
2904 | /** | 2906 | /** |
2905 | * ioc4_serial_init - module init | 2907 | * ioc4_serial_init - module init |
2906 | */ | 2908 | */ |
2907 | int ioc4_serial_init(void) | 2909 | static int __init ioc4_serial_init(void) |
2908 | { | 2910 | { |
2909 | int ret; | 2911 | int ret; |
2910 | 2912 | ||
@@ -2913,20 +2915,30 @@ int ioc4_serial_init(void) | |||
2913 | printk(KERN_WARNING | 2915 | printk(KERN_WARNING |
2914 | "%s: Couldn't register rs232 IOC4 serial driver\n", | 2916 | "%s: Couldn't register rs232 IOC4 serial driver\n", |
2915 | __func__); | 2917 | __func__); |
2916 | return ret; | 2918 | goto out; |
2917 | } | 2919 | } |
2918 | if ((ret = uart_register_driver(&ioc4_uart_rs422)) < 0) { | 2920 | if ((ret = uart_register_driver(&ioc4_uart_rs422)) < 0) { |
2919 | printk(KERN_WARNING | 2921 | printk(KERN_WARNING |
2920 | "%s: Couldn't register rs422 IOC4 serial driver\n", | 2922 | "%s: Couldn't register rs422 IOC4 serial driver\n", |
2921 | __func__); | 2923 | __func__); |
2922 | return ret; | 2924 | goto out_uart_rs232; |
2923 | } | 2925 | } |
2924 | 2926 | ||
2925 | /* register with IOC4 main module */ | 2927 | /* register with IOC4 main module */ |
2926 | return ioc4_register_submodule(&ioc4_serial_submodule); | 2928 | ret = ioc4_register_submodule(&ioc4_serial_submodule); |
2929 | if (ret) | ||
2930 | goto out_uart_rs422; | ||
2931 | return 0; | ||
2932 | |||
2933 | out_uart_rs422: | ||
2934 | uart_unregister_driver(&ioc4_uart_rs422); | ||
2935 | out_uart_rs232: | ||
2936 | uart_unregister_driver(&ioc4_uart_rs232); | ||
2937 | out: | ||
2938 | return ret; | ||
2927 | } | 2939 | } |
2928 | 2940 | ||
2929 | static void __devexit ioc4_serial_exit(void) | 2941 | static void __exit ioc4_serial_exit(void) |
2930 | { | 2942 | { |
2931 | ioc4_unregister_submodule(&ioc4_serial_submodule); | 2943 | ioc4_unregister_submodule(&ioc4_serial_submodule); |
2932 | uart_unregister_driver(&ioc4_uart_rs232); | 2944 | uart_unregister_driver(&ioc4_uart_rs232); |
diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c index 0d9acbd0bb70..ebff4a1d4bcc 100644 --- a/drivers/serial/ip22zilog.c +++ b/drivers/serial/ip22zilog.c | |||
@@ -256,9 +256,9 @@ static struct tty_struct *ip22zilog_receive_chars(struct uart_ip22zilog_port *up | |||
256 | unsigned int r1; | 256 | unsigned int r1; |
257 | 257 | ||
258 | tty = NULL; | 258 | tty = NULL; |
259 | if (up->port.info != NULL && | 259 | if (up->port.state != NULL && |
260 | up->port.info->port.tty != NULL) | 260 | up->port.state->port.tty != NULL) |
261 | tty = up->port.info->port.tty; | 261 | tty = up->port.state->port.tty; |
262 | 262 | ||
263 | for (;;) { | 263 | for (;;) { |
264 | ch = readb(&channel->control); | 264 | ch = readb(&channel->control); |
@@ -354,7 +354,7 @@ static void ip22zilog_status_handle(struct uart_ip22zilog_port *up, | |||
354 | uart_handle_cts_change(&up->port, | 354 | uart_handle_cts_change(&up->port, |
355 | (status & CTS)); | 355 | (status & CTS)); |
356 | 356 | ||
357 | wake_up_interruptible(&up->port.info->delta_msr_wait); | 357 | wake_up_interruptible(&up->port.state->port.delta_msr_wait); |
358 | } | 358 | } |
359 | 359 | ||
360 | up->prev_status = status; | 360 | up->prev_status = status; |
@@ -404,9 +404,9 @@ static void ip22zilog_transmit_chars(struct uart_ip22zilog_port *up, | |||
404 | return; | 404 | return; |
405 | } | 405 | } |
406 | 406 | ||
407 | if (up->port.info == NULL) | 407 | if (up->port.state == NULL) |
408 | goto ack_tx_int; | 408 | goto ack_tx_int; |
409 | xmit = &up->port.info->xmit; | 409 | xmit = &up->port.state->xmit; |
410 | if (uart_circ_empty(xmit)) | 410 | if (uart_circ_empty(xmit)) |
411 | goto ack_tx_int; | 411 | goto ack_tx_int; |
412 | if (uart_tx_stopped(&up->port)) | 412 | if (uart_tx_stopped(&up->port)) |
@@ -607,7 +607,7 @@ static void ip22zilog_start_tx(struct uart_port *port) | |||
607 | port->icount.tx++; | 607 | port->icount.tx++; |
608 | port->x_char = 0; | 608 | port->x_char = 0; |
609 | } else { | 609 | } else { |
610 | struct circ_buf *xmit = &port->info->xmit; | 610 | struct circ_buf *xmit = &port->state->xmit; |
611 | 611 | ||
612 | writeb(xmit->buf[xmit->tail], &channel->data); | 612 | writeb(xmit->buf[xmit->tail], &channel->data); |
613 | ZSDELAY(); | 613 | ZSDELAY(); |
diff --git a/drivers/serial/jsm/jsm.h b/drivers/serial/jsm/jsm.h index 4e5f3bde0461..38a509c684cd 100644 --- a/drivers/serial/jsm/jsm.h +++ b/drivers/serial/jsm/jsm.h | |||
@@ -138,7 +138,6 @@ struct jsm_board | |||
138 | u32 nasync; /* Number of ports on card */ | 138 | u32 nasync; /* Number of ports on card */ |
139 | 139 | ||
140 | u32 irq; /* Interrupt request number */ | 140 | u32 irq; /* Interrupt request number */ |
141 | u64 intr_count; /* Count of interrupts */ | ||
142 | 141 | ||
143 | u64 membase; /* Start of base memory of the card */ | 142 | u64 membase; /* Start of base memory of the card */ |
144 | u64 membase_end; /* End of base memory of the card */ | 143 | u64 membase_end; /* End of base memory of the card */ |
@@ -206,8 +205,6 @@ struct jsm_channel { | |||
206 | 205 | ||
207 | u64 ch_close_delay; /* How long we should drop RTS/DTR for */ | 206 | u64 ch_close_delay; /* How long we should drop RTS/DTR for */ |
208 | 207 | ||
209 | u64 ch_cpstime; /* Time for CPS calculations */ | ||
210 | |||
211 | tcflag_t ch_c_iflag; /* channel iflags */ | 208 | tcflag_t ch_c_iflag; /* channel iflags */ |
212 | tcflag_t ch_c_cflag; /* channel cflags */ | 209 | tcflag_t ch_c_cflag; /* channel cflags */ |
213 | tcflag_t ch_c_oflag; /* channel oflags */ | 210 | tcflag_t ch_c_oflag; /* channel oflags */ |
@@ -215,11 +212,6 @@ struct jsm_channel { | |||
215 | u8 ch_stopc; /* Stop character */ | 212 | u8 ch_stopc; /* Stop character */ |
216 | u8 ch_startc; /* Start character */ | 213 | u8 ch_startc; /* Start character */ |
217 | 214 | ||
218 | u32 ch_old_baud; /* Cache of the current baud */ | ||
219 | u32 ch_custom_speed;/* Custom baud, if set */ | ||
220 | |||
221 | u32 ch_wopen; /* Waiting for open process cnt */ | ||
222 | |||
223 | u8 ch_mostat; /* FEP output modem status */ | 215 | u8 ch_mostat; /* FEP output modem status */ |
224 | u8 ch_mistat; /* FEP input modem status */ | 216 | u8 ch_mistat; /* FEP input modem status */ |
225 | 217 | ||
diff --git a/drivers/serial/jsm/jsm_driver.c b/drivers/serial/jsm/jsm_driver.c index b3604aa322a4..18f548449c63 100644 --- a/drivers/serial/jsm/jsm_driver.c +++ b/drivers/serial/jsm/jsm_driver.c | |||
@@ -26,6 +26,7 @@ | |||
26 | ***********************************************************************/ | 26 | ***********************************************************************/ |
27 | #include <linux/moduleparam.h> | 27 | #include <linux/moduleparam.h> |
28 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
29 | #include <linux/slab.h> | ||
29 | 30 | ||
30 | #include "jsm.h" | 31 | #include "jsm.h" |
31 | 32 | ||
@@ -48,6 +49,17 @@ struct uart_driver jsm_uart_driver = { | |||
48 | .nr = NR_PORTS, | 49 | .nr = NR_PORTS, |
49 | }; | 50 | }; |
50 | 51 | ||
52 | static pci_ers_result_t jsm_io_error_detected(struct pci_dev *pdev, | ||
53 | pci_channel_state_t state); | ||
54 | static pci_ers_result_t jsm_io_slot_reset(struct pci_dev *pdev); | ||
55 | static void jsm_io_resume(struct pci_dev *pdev); | ||
56 | |||
57 | static struct pci_error_handlers jsm_err_handler = { | ||
58 | .error_detected = jsm_io_error_detected, | ||
59 | .slot_reset = jsm_io_slot_reset, | ||
60 | .resume = jsm_io_resume, | ||
61 | }; | ||
62 | |||
51 | int jsm_debug; | 63 | int jsm_debug; |
52 | module_param(jsm_debug, int, 0); | 64 | module_param(jsm_debug, int, 0); |
53 | MODULE_PARM_DESC(jsm_debug, "Driver debugging level"); | 65 | MODULE_PARM_DESC(jsm_debug, "Driver debugging level"); |
@@ -123,7 +135,7 @@ static int __devinit jsm_probe_one(struct pci_dev *pdev, const struct pci_device | |||
123 | } | 135 | } |
124 | 136 | ||
125 | rc = request_irq(brd->irq, brd->bd_ops->intr, | 137 | rc = request_irq(brd->irq, brd->bd_ops->intr, |
126 | IRQF_DISABLED|IRQF_SHARED, "JSM", brd); | 138 | IRQF_SHARED, "JSM", brd); |
127 | if (rc) { | 139 | if (rc) { |
128 | printk(KERN_WARNING "Failed to hook IRQ %d\n",brd->irq); | 140 | printk(KERN_WARNING "Failed to hook IRQ %d\n",brd->irq); |
129 | goto out_iounmap; | 141 | goto out_iounmap; |
@@ -160,13 +172,17 @@ static int __devinit jsm_probe_one(struct pci_dev *pdev, const struct pci_device | |||
160 | jsm_uart_port_init here! */ | 172 | jsm_uart_port_init here! */ |
161 | dev_err(&pdev->dev, "memory allocation for flipbuf failed\n"); | 173 | dev_err(&pdev->dev, "memory allocation for flipbuf failed\n"); |
162 | rc = -ENOMEM; | 174 | rc = -ENOMEM; |
163 | goto out_free_irq; | 175 | goto out_free_uart; |
164 | } | 176 | } |
165 | 177 | ||
166 | pci_set_drvdata(pdev, brd); | 178 | pci_set_drvdata(pdev, brd); |
179 | pci_save_state(pdev); | ||
167 | 180 | ||
168 | return 0; | 181 | return 0; |
182 | out_free_uart: | ||
183 | jsm_remove_uart_port(brd); | ||
169 | out_free_irq: | 184 | out_free_irq: |
185 | jsm_remove_uart_port(brd); | ||
170 | free_irq(brd->irq, brd); | 186 | free_irq(brd->irq, brd); |
171 | out_iounmap: | 187 | out_iounmap: |
172 | iounmap(brd->re_map_membase); | 188 | iounmap(brd->re_map_membase); |
@@ -222,8 +238,42 @@ static struct pci_driver jsm_driver = { | |||
222 | .id_table = jsm_pci_tbl, | 238 | .id_table = jsm_pci_tbl, |
223 | .probe = jsm_probe_one, | 239 | .probe = jsm_probe_one, |
224 | .remove = __devexit_p(jsm_remove_one), | 240 | .remove = __devexit_p(jsm_remove_one), |
241 | .err_handler = &jsm_err_handler, | ||
225 | }; | 242 | }; |
226 | 243 | ||
244 | static pci_ers_result_t jsm_io_error_detected(struct pci_dev *pdev, | ||
245 | pci_channel_state_t state) | ||
246 | { | ||
247 | struct jsm_board *brd = pci_get_drvdata(pdev); | ||
248 | |||
249 | jsm_remove_uart_port(brd); | ||
250 | |||
251 | return PCI_ERS_RESULT_NEED_RESET; | ||
252 | } | ||
253 | |||
254 | static pci_ers_result_t jsm_io_slot_reset(struct pci_dev *pdev) | ||
255 | { | ||
256 | int rc; | ||
257 | |||
258 | rc = pci_enable_device(pdev); | ||
259 | |||
260 | if (rc) | ||
261 | return PCI_ERS_RESULT_DISCONNECT; | ||
262 | |||
263 | pci_set_master(pdev); | ||
264 | |||
265 | return PCI_ERS_RESULT_RECOVERED; | ||
266 | } | ||
267 | |||
268 | static void jsm_io_resume(struct pci_dev *pdev) | ||
269 | { | ||
270 | struct jsm_board *brd = pci_get_drvdata(pdev); | ||
271 | |||
272 | pci_restore_state(pdev); | ||
273 | |||
274 | jsm_uart_port_init(brd); | ||
275 | } | ||
276 | |||
227 | static int __init jsm_init_module(void) | 277 | static int __init jsm_init_module(void) |
228 | { | 278 | { |
229 | int rc; | 279 | int rc; |
diff --git a/drivers/serial/jsm/jsm_neo.c b/drivers/serial/jsm/jsm_neo.c index 9dadaa11d266..7960d9633c15 100644 --- a/drivers/serial/jsm/jsm_neo.c +++ b/drivers/serial/jsm/jsm_neo.c | |||
@@ -954,13 +954,8 @@ static void neo_param(struct jsm_channel *ch) | |||
954 | ch->ch_flags |= (CH_BAUD0); | 954 | ch->ch_flags |= (CH_BAUD0); |
955 | ch->ch_mostat &= ~(UART_MCR_RTS | UART_MCR_DTR); | 955 | ch->ch_mostat &= ~(UART_MCR_RTS | UART_MCR_DTR); |
956 | neo_assert_modem_signals(ch); | 956 | neo_assert_modem_signals(ch); |
957 | ch->ch_old_baud = 0; | ||
958 | return; | 957 | return; |
959 | 958 | ||
960 | } else if (ch->ch_custom_speed) { | ||
961 | baud = ch->ch_custom_speed; | ||
962 | if (ch->ch_flags & CH_BAUD0) | ||
963 | ch->ch_flags &= ~(CH_BAUD0); | ||
964 | } else { | 959 | } else { |
965 | int i; | 960 | int i; |
966 | unsigned int cflag; | 961 | unsigned int cflag; |
@@ -989,7 +984,7 @@ static void neo_param(struct jsm_channel *ch) | |||
989 | { 50, B50 }, | 984 | { 50, B50 }, |
990 | }; | 985 | }; |
991 | 986 | ||
992 | cflag = C_BAUD(ch->uart_port.info->port.tty); | 987 | cflag = C_BAUD(ch->uart_port.state->port.tty); |
993 | baud = 9600; | 988 | baud = 9600; |
994 | for (i = 0; i < ARRAY_SIZE(baud_rates); i++) { | 989 | for (i = 0; i < ARRAY_SIZE(baud_rates); i++) { |
995 | if (baud_rates[i].cflag == cflag) { | 990 | if (baud_rates[i].cflag == cflag) { |
@@ -1045,7 +1040,6 @@ static void neo_param(struct jsm_channel *ch) | |||
1045 | quot = ch->ch_bd->bd_dividend / baud; | 1040 | quot = ch->ch_bd->bd_dividend / baud; |
1046 | 1041 | ||
1047 | if (quot != 0) { | 1042 | if (quot != 0) { |
1048 | ch->ch_old_baud = baud; | ||
1049 | writeb(UART_LCR_DLAB, &ch->ch_neo_uart->lcr); | 1043 | writeb(UART_LCR_DLAB, &ch->ch_neo_uart->lcr); |
1050 | writeb((quot & 0xff), &ch->ch_neo_uart->txrx); | 1044 | writeb((quot & 0xff), &ch->ch_neo_uart->txrx); |
1051 | writeb((quot >> 8), &ch->ch_neo_uart->ier); | 1045 | writeb((quot >> 8), &ch->ch_neo_uart->ier); |
@@ -1123,8 +1117,6 @@ static irqreturn_t neo_intr(int irq, void *voidbrd) | |||
1123 | unsigned long lock_flags2; | 1117 | unsigned long lock_flags2; |
1124 | int outofloop_count = 0; | 1118 | int outofloop_count = 0; |
1125 | 1119 | ||
1126 | brd->intr_count++; | ||
1127 | |||
1128 | /* Lock out the slow poller from running on this board. */ | 1120 | /* Lock out the slow poller from running on this board. */ |
1129 | spin_lock_irqsave(&brd->bd_intr_lock, lock_flags); | 1121 | spin_lock_irqsave(&brd->bd_intr_lock, lock_flags); |
1130 | 1122 | ||
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c index 107ce2e187b8..7a4a914ecff0 100644 --- a/drivers/serial/jsm/jsm_tty.c +++ b/drivers/serial/jsm/jsm_tty.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/serial_reg.h> | 30 | #include <linux/serial_reg.h> |
31 | #include <linux/delay.h> /* For udelay */ | 31 | #include <linux/delay.h> /* For udelay */ |
32 | #include <linux/pci.h> | 32 | #include <linux/pci.h> |
33 | #include <linux/slab.h> | ||
33 | 34 | ||
34 | #include "jsm.h" | 35 | #include "jsm.h" |
35 | 36 | ||
@@ -147,7 +148,7 @@ static void jsm_tty_send_xchar(struct uart_port *port, char ch) | |||
147 | struct ktermios *termios; | 148 | struct ktermios *termios; |
148 | 149 | ||
149 | spin_lock_irqsave(&port->lock, lock_flags); | 150 | spin_lock_irqsave(&port->lock, lock_flags); |
150 | termios = port->info->port.tty->termios; | 151 | termios = port->state->port.tty->termios; |
151 | if (ch == termios->c_cc[VSTART]) | 152 | if (ch == termios->c_cc[VSTART]) |
152 | channel->ch_bd->bd_ops->send_start_character(channel); | 153 | channel->ch_bd->bd_ops->send_start_character(channel); |
153 | 154 | ||
@@ -245,7 +246,7 @@ static int jsm_tty_open(struct uart_port *port) | |||
245 | channel->ch_cached_lsr = 0; | 246 | channel->ch_cached_lsr = 0; |
246 | channel->ch_stops_sent = 0; | 247 | channel->ch_stops_sent = 0; |
247 | 248 | ||
248 | termios = port->info->port.tty->termios; | 249 | termios = port->state->port.tty->termios; |
249 | channel->ch_c_cflag = termios->c_cflag; | 250 | channel->ch_c_cflag = termios->c_cflag; |
250 | channel->ch_c_iflag = termios->c_iflag; | 251 | channel->ch_c_iflag = termios->c_iflag; |
251 | channel->ch_c_oflag = termios->c_oflag; | 252 | channel->ch_c_oflag = termios->c_oflag; |
@@ -278,7 +279,7 @@ static void jsm_tty_close(struct uart_port *port) | |||
278 | jsm_printk(CLOSE, INFO, &channel->ch_bd->pci_dev, "start\n"); | 279 | jsm_printk(CLOSE, INFO, &channel->ch_bd->pci_dev, "start\n"); |
279 | 280 | ||
280 | bd = channel->ch_bd; | 281 | bd = channel->ch_bd; |
281 | ts = port->info->port.tty->termios; | 282 | ts = port->state->port.tty->termios; |
282 | 283 | ||
283 | channel->ch_flags &= ~(CH_STOPI); | 284 | channel->ch_flags &= ~(CH_STOPI); |
284 | 285 | ||
@@ -296,8 +297,6 @@ static void jsm_tty_close(struct uart_port *port) | |||
296 | bd->bd_ops->assert_modem_signals(channel); | 297 | bd->bd_ops->assert_modem_signals(channel); |
297 | } | 298 | } |
298 | 299 | ||
299 | channel->ch_old_baud = 0; | ||
300 | |||
301 | /* Turn off UART interrupts for this port */ | 300 | /* Turn off UART interrupts for this port */ |
302 | channel->ch_bd->bd_ops->uart_off(channel); | 301 | channel->ch_bd->bd_ops->uart_off(channel); |
303 | 302 | ||
@@ -432,9 +431,9 @@ int __devinit jsm_tty_init(struct jsm_board *brd) | |||
432 | return 0; | 431 | return 0; |
433 | } | 432 | } |
434 | 433 | ||
435 | int __devinit jsm_uart_port_init(struct jsm_board *brd) | 434 | int jsm_uart_port_init(struct jsm_board *brd) |
436 | { | 435 | { |
437 | int i; | 436 | int i, rc; |
438 | unsigned int line; | 437 | unsigned int line; |
439 | struct jsm_channel *ch; | 438 | struct jsm_channel *ch; |
440 | 439 | ||
@@ -467,12 +466,15 @@ int __devinit jsm_uart_port_init(struct jsm_board *brd) | |||
467 | printk(KERN_INFO "jsm: linemap is full, added device failed\n"); | 466 | printk(KERN_INFO "jsm: linemap is full, added device failed\n"); |
468 | continue; | 467 | continue; |
469 | } else | 468 | } else |
470 | set_bit((int)line, linemap); | 469 | set_bit(line, linemap); |
471 | brd->channels[i]->uart_port.line = line; | 470 | brd->channels[i]->uart_port.line = line; |
472 | if (uart_add_one_port (&jsm_uart_driver, &brd->channels[i]->uart_port)) | 471 | rc = uart_add_one_port (&jsm_uart_driver, &brd->channels[i]->uart_port); |
473 | printk(KERN_INFO "jsm: add device failed\n"); | 472 | if (rc){ |
473 | printk(KERN_INFO "jsm: Port %d failed. Aborting...\n", i); | ||
474 | return rc; | ||
475 | } | ||
474 | else | 476 | else |
475 | printk(KERN_INFO "Added device \n"); | 477 | printk(KERN_INFO "jsm: Port %d added\n", i); |
476 | } | 478 | } |
477 | 479 | ||
478 | jsm_printk(INIT, INFO, &brd->pci_dev, "finish\n"); | 480 | jsm_printk(INIT, INFO, &brd->pci_dev, "finish\n"); |
@@ -503,7 +505,7 @@ int jsm_remove_uart_port(struct jsm_board *brd) | |||
503 | 505 | ||
504 | ch = brd->channels[i]; | 506 | ch = brd->channels[i]; |
505 | 507 | ||
506 | clear_bit((int)(ch->uart_port.line), linemap); | 508 | clear_bit(ch->uart_port.line, linemap); |
507 | uart_remove_one_port(&jsm_uart_driver, &brd->channels[i]->uart_port); | 509 | uart_remove_one_port(&jsm_uart_driver, &brd->channels[i]->uart_port); |
508 | } | 510 | } |
509 | 511 | ||
@@ -530,7 +532,7 @@ void jsm_input(struct jsm_channel *ch) | |||
530 | if (!ch) | 532 | if (!ch) |
531 | return; | 533 | return; |
532 | 534 | ||
533 | tp = ch->uart_port.info->port.tty; | 535 | tp = ch->uart_port.state->port.tty; |
534 | 536 | ||
535 | bd = ch->ch_bd; | 537 | bd = ch->ch_bd; |
536 | if(!bd) | 538 | if(!bd) |
@@ -849,7 +851,7 @@ int jsm_tty_write(struct uart_port *port) | |||
849 | u16 tail; | 851 | u16 tail; |
850 | u16 tmask; | 852 | u16 tmask; |
851 | u32 remain; | 853 | u32 remain; |
852 | int temp_tail = port->info->xmit.tail; | 854 | int temp_tail = port->state->xmit.tail; |
853 | struct jsm_channel *channel = (struct jsm_channel *)port; | 855 | struct jsm_channel *channel = (struct jsm_channel *)port; |
854 | 856 | ||
855 | tmask = WQUEUEMASK; | 857 | tmask = WQUEUEMASK; |
@@ -865,10 +867,10 @@ int jsm_tty_write(struct uart_port *port) | |||
865 | data_count = 0; | 867 | data_count = 0; |
866 | if (bufcount >= remain) { | 868 | if (bufcount >= remain) { |
867 | bufcount -= remain; | 869 | bufcount -= remain; |
868 | while ((port->info->xmit.head != temp_tail) && | 870 | while ((port->state->xmit.head != temp_tail) && |
869 | (data_count < remain)) { | 871 | (data_count < remain)) { |
870 | channel->ch_wqueue[head++] = | 872 | channel->ch_wqueue[head++] = |
871 | port->info->xmit.buf[temp_tail]; | 873 | port->state->xmit.buf[temp_tail]; |
872 | 874 | ||
873 | temp_tail++; | 875 | temp_tail++; |
874 | temp_tail &= (UART_XMIT_SIZE - 1); | 876 | temp_tail &= (UART_XMIT_SIZE - 1); |
@@ -880,10 +882,10 @@ int jsm_tty_write(struct uart_port *port) | |||
880 | data_count1 = 0; | 882 | data_count1 = 0; |
881 | if (bufcount > 0) { | 883 | if (bufcount > 0) { |
882 | remain = bufcount; | 884 | remain = bufcount; |
883 | while ((port->info->xmit.head != temp_tail) && | 885 | while ((port->state->xmit.head != temp_tail) && |
884 | (data_count1 < remain)) { | 886 | (data_count1 < remain)) { |
885 | channel->ch_wqueue[head++] = | 887 | channel->ch_wqueue[head++] = |
886 | port->info->xmit.buf[temp_tail]; | 888 | port->state->xmit.buf[temp_tail]; |
887 | 889 | ||
888 | temp_tail++; | 890 | temp_tail++; |
889 | temp_tail &= (UART_XMIT_SIZE - 1); | 891 | temp_tail &= (UART_XMIT_SIZE - 1); |
@@ -892,7 +894,7 @@ int jsm_tty_write(struct uart_port *port) | |||
892 | } | 894 | } |
893 | } | 895 | } |
894 | 896 | ||
895 | port->info->xmit.tail = temp_tail; | 897 | port->state->xmit.tail = temp_tail; |
896 | 898 | ||
897 | data_count += data_count1; | 899 | data_count += data_count1; |
898 | if (data_count) { | 900 | if (data_count) { |
diff --git a/drivers/serial/kgdboc.c b/drivers/serial/kgdboc.c index eadc1ab6bbce..25a8bc565f40 100644 --- a/drivers/serial/kgdboc.c +++ b/drivers/serial/kgdboc.c | |||
@@ -14,7 +14,11 @@ | |||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/ctype.h> | 15 | #include <linux/ctype.h> |
16 | #include <linux/kgdb.h> | 16 | #include <linux/kgdb.h> |
17 | #include <linux/kdb.h> | ||
17 | #include <linux/tty.h> | 18 | #include <linux/tty.h> |
19 | #include <linux/console.h> | ||
20 | #include <linux/vt_kern.h> | ||
21 | #include <linux/input.h> | ||
18 | 22 | ||
19 | #define MAX_CONFIG_LEN 40 | 23 | #define MAX_CONFIG_LEN 40 |
20 | 24 | ||
@@ -29,9 +33,102 @@ static struct kparam_string kps = { | |||
29 | .maxlen = MAX_CONFIG_LEN, | 33 | .maxlen = MAX_CONFIG_LEN, |
30 | }; | 34 | }; |
31 | 35 | ||
36 | static int kgdboc_use_kms; /* 1 if we use kernel mode switching */ | ||
32 | static struct tty_driver *kgdb_tty_driver; | 37 | static struct tty_driver *kgdb_tty_driver; |
33 | static int kgdb_tty_line; | 38 | static int kgdb_tty_line; |
34 | 39 | ||
40 | #ifdef CONFIG_KDB_KEYBOARD | ||
41 | static int kgdboc_reset_connect(struct input_handler *handler, | ||
42 | struct input_dev *dev, | ||
43 | const struct input_device_id *id) | ||
44 | { | ||
45 | input_reset_device(dev); | ||
46 | |||
47 | /* Retrun an error - we do not want to bind, just to reset */ | ||
48 | return -ENODEV; | ||
49 | } | ||
50 | |||
51 | static void kgdboc_reset_disconnect(struct input_handle *handle) | ||
52 | { | ||
53 | /* We do not expect anyone to actually bind to us */ | ||
54 | BUG(); | ||
55 | } | ||
56 | |||
57 | static const struct input_device_id kgdboc_reset_ids[] = { | ||
58 | { | ||
59 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT, | ||
60 | .evbit = { BIT_MASK(EV_KEY) }, | ||
61 | }, | ||
62 | { } | ||
63 | }; | ||
64 | |||
65 | static struct input_handler kgdboc_reset_handler = { | ||
66 | .connect = kgdboc_reset_connect, | ||
67 | .disconnect = kgdboc_reset_disconnect, | ||
68 | .name = "kgdboc_reset", | ||
69 | .id_table = kgdboc_reset_ids, | ||
70 | }; | ||
71 | |||
72 | static DEFINE_MUTEX(kgdboc_reset_mutex); | ||
73 | |||
74 | static void kgdboc_restore_input_helper(struct work_struct *dummy) | ||
75 | { | ||
76 | /* | ||
77 | * We need to take a mutex to prevent several instances of | ||
78 | * this work running on different CPUs so they don't try | ||
79 | * to register again already registered handler. | ||
80 | */ | ||
81 | mutex_lock(&kgdboc_reset_mutex); | ||
82 | |||
83 | if (input_register_handler(&kgdboc_reset_handler) == 0) | ||
84 | input_unregister_handler(&kgdboc_reset_handler); | ||
85 | |||
86 | mutex_unlock(&kgdboc_reset_mutex); | ||
87 | } | ||
88 | |||
89 | static DECLARE_WORK(kgdboc_restore_input_work, kgdboc_restore_input_helper); | ||
90 | |||
91 | static void kgdboc_restore_input(void) | ||
92 | { | ||
93 | if (likely(system_state == SYSTEM_RUNNING)) | ||
94 | schedule_work(&kgdboc_restore_input_work); | ||
95 | } | ||
96 | |||
97 | static int kgdboc_register_kbd(char **cptr) | ||
98 | { | ||
99 | if (strncmp(*cptr, "kbd", 3) == 0) { | ||
100 | if (kdb_poll_idx < KDB_POLL_FUNC_MAX) { | ||
101 | kdb_poll_funcs[kdb_poll_idx] = kdb_get_kbd_char; | ||
102 | kdb_poll_idx++; | ||
103 | if (cptr[0][3] == ',') | ||
104 | *cptr += 4; | ||
105 | else | ||
106 | return 1; | ||
107 | } | ||
108 | } | ||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | static void kgdboc_unregister_kbd(void) | ||
113 | { | ||
114 | int i; | ||
115 | |||
116 | for (i = 0; i < kdb_poll_idx; i++) { | ||
117 | if (kdb_poll_funcs[i] == kdb_get_kbd_char) { | ||
118 | kdb_poll_idx--; | ||
119 | kdb_poll_funcs[i] = kdb_poll_funcs[kdb_poll_idx]; | ||
120 | kdb_poll_funcs[kdb_poll_idx] = NULL; | ||
121 | i--; | ||
122 | } | ||
123 | } | ||
124 | flush_work_sync(&kgdboc_restore_input_work); | ||
125 | } | ||
126 | #else /* ! CONFIG_KDB_KEYBOARD */ | ||
127 | #define kgdboc_register_kbd(x) 0 | ||
128 | #define kgdboc_unregister_kbd() | ||
129 | #define kgdboc_restore_input() | ||
130 | #endif /* ! CONFIG_KDB_KEYBOARD */ | ||
131 | |||
35 | static int kgdboc_option_setup(char *opt) | 132 | static int kgdboc_option_setup(char *opt) |
36 | { | 133 | { |
37 | if (strlen(opt) > MAX_CONFIG_LEN) { | 134 | if (strlen(opt) > MAX_CONFIG_LEN) { |
@@ -45,25 +142,57 @@ static int kgdboc_option_setup(char *opt) | |||
45 | 142 | ||
46 | __setup("kgdboc=", kgdboc_option_setup); | 143 | __setup("kgdboc=", kgdboc_option_setup); |
47 | 144 | ||
145 | static void cleanup_kgdboc(void) | ||
146 | { | ||
147 | kgdboc_unregister_kbd(); | ||
148 | if (configured == 1) | ||
149 | kgdb_unregister_io_module(&kgdboc_io_ops); | ||
150 | } | ||
151 | |||
48 | static int configure_kgdboc(void) | 152 | static int configure_kgdboc(void) |
49 | { | 153 | { |
50 | struct tty_driver *p; | 154 | struct tty_driver *p; |
51 | int tty_line = 0; | 155 | int tty_line = 0; |
52 | int err; | 156 | int err; |
157 | char *cptr = config; | ||
158 | struct console *cons; | ||
53 | 159 | ||
54 | err = kgdboc_option_setup(config); | 160 | err = kgdboc_option_setup(config); |
55 | if (err || !strlen(config) || isspace(config[0])) | 161 | if (err || !strlen(config) || isspace(config[0])) |
56 | goto noconfig; | 162 | goto noconfig; |
57 | 163 | ||
58 | err = -ENODEV; | 164 | err = -ENODEV; |
165 | kgdboc_io_ops.is_console = 0; | ||
166 | kgdb_tty_driver = NULL; | ||
167 | |||
168 | kgdboc_use_kms = 0; | ||
169 | if (strncmp(cptr, "kms,", 4) == 0) { | ||
170 | cptr += 4; | ||
171 | kgdboc_use_kms = 1; | ||
172 | } | ||
173 | |||
174 | if (kgdboc_register_kbd(&cptr)) | ||
175 | goto do_register; | ||
59 | 176 | ||
60 | p = tty_find_polling_driver(config, &tty_line); | 177 | p = tty_find_polling_driver(cptr, &tty_line); |
61 | if (!p) | 178 | if (!p) |
62 | goto noconfig; | 179 | goto noconfig; |
63 | 180 | ||
181 | cons = console_drivers; | ||
182 | while (cons) { | ||
183 | int idx; | ||
184 | if (cons->device && cons->device(cons, &idx) == p && | ||
185 | idx == tty_line) { | ||
186 | kgdboc_io_ops.is_console = 1; | ||
187 | break; | ||
188 | } | ||
189 | cons = cons->next; | ||
190 | } | ||
191 | |||
64 | kgdb_tty_driver = p; | 192 | kgdb_tty_driver = p; |
65 | kgdb_tty_line = tty_line; | 193 | kgdb_tty_line = tty_line; |
66 | 194 | ||
195 | do_register: | ||
67 | err = kgdb_register_io_module(&kgdboc_io_ops); | 196 | err = kgdb_register_io_module(&kgdboc_io_ops); |
68 | if (err) | 197 | if (err) |
69 | goto noconfig; | 198 | goto noconfig; |
@@ -75,6 +204,7 @@ static int configure_kgdboc(void) | |||
75 | noconfig: | 204 | noconfig: |
76 | config[0] = 0; | 205 | config[0] = 0; |
77 | configured = 0; | 206 | configured = 0; |
207 | cleanup_kgdboc(); | ||
78 | 208 | ||
79 | return err; | 209 | return err; |
80 | } | 210 | } |
@@ -88,20 +218,18 @@ static int __init init_kgdboc(void) | |||
88 | return configure_kgdboc(); | 218 | return configure_kgdboc(); |
89 | } | 219 | } |
90 | 220 | ||
91 | static void cleanup_kgdboc(void) | ||
92 | { | ||
93 | if (configured == 1) | ||
94 | kgdb_unregister_io_module(&kgdboc_io_ops); | ||
95 | } | ||
96 | |||
97 | static int kgdboc_get_char(void) | 221 | static int kgdboc_get_char(void) |
98 | { | 222 | { |
223 | if (!kgdb_tty_driver) | ||
224 | return -1; | ||
99 | return kgdb_tty_driver->ops->poll_get_char(kgdb_tty_driver, | 225 | return kgdb_tty_driver->ops->poll_get_char(kgdb_tty_driver, |
100 | kgdb_tty_line); | 226 | kgdb_tty_line); |
101 | } | 227 | } |
102 | 228 | ||
103 | static void kgdboc_put_char(u8 chr) | 229 | static void kgdboc_put_char(u8 chr) |
104 | { | 230 | { |
231 | if (!kgdb_tty_driver) | ||
232 | return; | ||
105 | kgdb_tty_driver->ops->poll_put_char(kgdb_tty_driver, | 233 | kgdb_tty_driver->ops->poll_put_char(kgdb_tty_driver, |
106 | kgdb_tty_line, chr); | 234 | kgdb_tty_line, chr); |
107 | } | 235 | } |
@@ -140,8 +268,14 @@ static int param_set_kgdboc_var(const char *kmessage, struct kernel_param *kp) | |||
140 | return configure_kgdboc(); | 268 | return configure_kgdboc(); |
141 | } | 269 | } |
142 | 270 | ||
271 | static int dbg_restore_graphics; | ||
272 | |||
143 | static void kgdboc_pre_exp_handler(void) | 273 | static void kgdboc_pre_exp_handler(void) |
144 | { | 274 | { |
275 | if (!dbg_restore_graphics && kgdboc_use_kms) { | ||
276 | dbg_restore_graphics = 1; | ||
277 | con_debug_enter(vc_cons[fg_console].d); | ||
278 | } | ||
145 | /* Increment the module count when the debugger is active */ | 279 | /* Increment the module count when the debugger is active */ |
146 | if (!kgdb_connected) | 280 | if (!kgdb_connected) |
147 | try_module_get(THIS_MODULE); | 281 | try_module_get(THIS_MODULE); |
@@ -152,6 +286,11 @@ static void kgdboc_post_exp_handler(void) | |||
152 | /* decrement the module count when the debugger detaches */ | 286 | /* decrement the module count when the debugger detaches */ |
153 | if (!kgdb_connected) | 287 | if (!kgdb_connected) |
154 | module_put(THIS_MODULE); | 288 | module_put(THIS_MODULE); |
289 | if (kgdboc_use_kms && dbg_restore_graphics) { | ||
290 | dbg_restore_graphics = 0; | ||
291 | con_debug_leave(); | ||
292 | } | ||
293 | kgdboc_restore_input(); | ||
155 | } | 294 | } |
156 | 295 | ||
157 | static struct kgdb_io kgdboc_io_ops = { | 296 | static struct kgdb_io kgdboc_io_ops = { |
@@ -162,6 +301,25 @@ static struct kgdb_io kgdboc_io_ops = { | |||
162 | .post_exception = kgdboc_post_exp_handler, | 301 | .post_exception = kgdboc_post_exp_handler, |
163 | }; | 302 | }; |
164 | 303 | ||
304 | #ifdef CONFIG_KGDB_SERIAL_CONSOLE | ||
305 | /* This is only available if kgdboc is a built in for early debugging */ | ||
306 | static int __init kgdboc_early_init(char *opt) | ||
307 | { | ||
308 | /* save the first character of the config string because the | ||
309 | * init routine can destroy it. | ||
310 | */ | ||
311 | char save_ch; | ||
312 | |||
313 | kgdboc_option_setup(opt); | ||
314 | save_ch = config[0]; | ||
315 | init_kgdboc(); | ||
316 | config[0] = save_ch; | ||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | early_param("ekgdboc", kgdboc_early_init); | ||
321 | #endif /* CONFIG_KGDB_SERIAL_CONSOLE */ | ||
322 | |||
165 | module_init(init_kgdboc); | 323 | module_init(init_kgdboc); |
166 | module_exit(cleanup_kgdboc); | 324 | module_exit(cleanup_kgdboc); |
167 | module_param_call(kgdboc, param_set_kgdboc_var, param_get_string, &kps, 0644); | 325 | module_param_call(kgdboc, param_set_kgdboc_var, param_get_string, &kps, 0644); |
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c index 611c97a15654..bea5c215460c 100644 --- a/drivers/serial/m32r_sio.c +++ b/drivers/serial/m32r_sio.c | |||
@@ -286,7 +286,7 @@ static void m32r_sio_start_tx(struct uart_port *port) | |||
286 | { | 286 | { |
287 | #ifdef CONFIG_SERIAL_M32R_PLDSIO | 287 | #ifdef CONFIG_SERIAL_M32R_PLDSIO |
288 | struct uart_sio_port *up = (struct uart_sio_port *)port; | 288 | struct uart_sio_port *up = (struct uart_sio_port *)port; |
289 | struct circ_buf *xmit = &up->port.info->xmit; | 289 | struct circ_buf *xmit = &up->port.state->xmit; |
290 | 290 | ||
291 | if (!(up->ier & UART_IER_THRI)) { | 291 | if (!(up->ier & UART_IER_THRI)) { |
292 | up->ier |= UART_IER_THRI; | 292 | up->ier |= UART_IER_THRI; |
@@ -325,7 +325,7 @@ static void m32r_sio_enable_ms(struct uart_port *port) | |||
325 | 325 | ||
326 | static void receive_chars(struct uart_sio_port *up, int *status) | 326 | static void receive_chars(struct uart_sio_port *up, int *status) |
327 | { | 327 | { |
328 | struct tty_struct *tty = up->port.info->port.tty; | 328 | struct tty_struct *tty = up->port.state->port.tty; |
329 | unsigned char ch; | 329 | unsigned char ch; |
330 | unsigned char flag; | 330 | unsigned char flag; |
331 | int max_count = 256; | 331 | int max_count = 256; |
@@ -398,7 +398,7 @@ static void receive_chars(struct uart_sio_port *up, int *status) | |||
398 | 398 | ||
399 | static void transmit_chars(struct uart_sio_port *up) | 399 | static void transmit_chars(struct uart_sio_port *up) |
400 | { | 400 | { |
401 | struct circ_buf *xmit = &up->port.info->xmit; | 401 | struct circ_buf *xmit = &up->port.state->xmit; |
402 | int count; | 402 | int count; |
403 | 403 | ||
404 | if (up->port.x_char) { | 404 | if (up->port.x_char) { |
diff --git a/drivers/serial/max3100.c b/drivers/serial/max3100.c index 9fd33e5622bd..beb1afa27d8d 100644 --- a/drivers/serial/max3100.c +++ b/drivers/serial/max3100.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #define MAX_MAX3100 4 | 41 | #define MAX_MAX3100 4 |
42 | 42 | ||
43 | #include <linux/delay.h> | 43 | #include <linux/delay.h> |
44 | #include <linux/slab.h> | ||
44 | #include <linux/device.h> | 45 | #include <linux/device.h> |
45 | #include <linux/serial_core.h> | 46 | #include <linux/serial_core.h> |
46 | #include <linux/serial.h> | 47 | #include <linux/serial.h> |
@@ -184,7 +185,7 @@ static void max3100_timeout(unsigned long data) | |||
184 | { | 185 | { |
185 | struct max3100_port *s = (struct max3100_port *)data; | 186 | struct max3100_port *s = (struct max3100_port *)data; |
186 | 187 | ||
187 | if (s->port.info) { | 188 | if (s->port.state) { |
188 | max3100_dowork(s); | 189 | max3100_dowork(s); |
189 | mod_timer(&s->timer, jiffies + s->poll_time); | 190 | mod_timer(&s->timer, jiffies + s->poll_time); |
190 | } | 191 | } |
@@ -261,7 +262,7 @@ static void max3100_work(struct work_struct *w) | |||
261 | int rxchars; | 262 | int rxchars; |
262 | u16 tx, rx; | 263 | u16 tx, rx; |
263 | int conf, cconf, rts, crts; | 264 | int conf, cconf, rts, crts; |
264 | struct circ_buf *xmit = &s->port.info->xmit; | 265 | struct circ_buf *xmit = &s->port.state->xmit; |
265 | 266 | ||
266 | dev_dbg(&s->spi->dev, "%s\n", __func__); | 267 | dev_dbg(&s->spi->dev, "%s\n", __func__); |
267 | 268 | ||
@@ -307,8 +308,8 @@ static void max3100_work(struct work_struct *w) | |||
307 | } | 308 | } |
308 | } | 309 | } |
309 | 310 | ||
310 | if (rxchars > 16 && s->port.info->port.tty != NULL) { | 311 | if (rxchars > 16 && s->port.state->port.tty != NULL) { |
311 | tty_flip_buffer_push(s->port.info->port.tty); | 312 | tty_flip_buffer_push(s->port.state->port.tty); |
312 | rxchars = 0; | 313 | rxchars = 0; |
313 | } | 314 | } |
314 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 315 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
@@ -320,8 +321,8 @@ static void max3100_work(struct work_struct *w) | |||
320 | (!uart_circ_empty(xmit) && | 321 | (!uart_circ_empty(xmit) && |
321 | !uart_tx_stopped(&s->port)))); | 322 | !uart_tx_stopped(&s->port)))); |
322 | 323 | ||
323 | if (rxchars > 0 && s->port.info->port.tty != NULL) | 324 | if (rxchars > 0 && s->port.state->port.tty != NULL) |
324 | tty_flip_buffer_push(s->port.info->port.tty); | 325 | tty_flip_buffer_push(s->port.state->port.tty); |
325 | } | 326 | } |
326 | 327 | ||
327 | static irqreturn_t max3100_irq(int irqno, void *dev_id) | 328 | static irqreturn_t max3100_irq(int irqno, void *dev_id) |
@@ -429,17 +430,14 @@ max3100_set_termios(struct uart_port *port, struct ktermios *termios, | |||
429 | int baud = 0; | 430 | int baud = 0; |
430 | unsigned cflag; | 431 | unsigned cflag; |
431 | u32 param_new, param_mask, parity = 0; | 432 | u32 param_new, param_mask, parity = 0; |
432 | struct tty_struct *tty = s->port.info->port.tty; | ||
433 | 433 | ||
434 | dev_dbg(&s->spi->dev, "%s\n", __func__); | 434 | dev_dbg(&s->spi->dev, "%s\n", __func__); |
435 | if (!tty) | ||
436 | return; | ||
437 | 435 | ||
438 | cflag = termios->c_cflag; | 436 | cflag = termios->c_cflag; |
439 | param_new = 0; | 437 | param_new = 0; |
440 | param_mask = 0; | 438 | param_mask = 0; |
441 | 439 | ||
442 | baud = tty_get_baud_rate(tty); | 440 | baud = tty_termios_baud_rate(termios); |
443 | param_new = s->conf & MAX3100_BAUD; | 441 | param_new = s->conf & MAX3100_BAUD; |
444 | switch (baud) { | 442 | switch (baud) { |
445 | case 300: | 443 | case 300: |
@@ -484,7 +482,7 @@ max3100_set_termios(struct uart_port *port, struct ktermios *termios, | |||
484 | default: | 482 | default: |
485 | baud = s->baud; | 483 | baud = s->baud; |
486 | } | 484 | } |
487 | tty_encode_baud_rate(tty, baud, baud); | 485 | tty_termios_encode_baud_rate(termios, baud, baud); |
488 | s->baud = baud; | 486 | s->baud = baud; |
489 | param_mask |= MAX3100_BAUD; | 487 | param_mask |= MAX3100_BAUD; |
490 | 488 | ||
@@ -529,7 +527,7 @@ max3100_set_termios(struct uart_port *port, struct ktermios *termios, | |||
529 | MAX3100_STATUS_OE; | 527 | MAX3100_STATUS_OE; |
530 | 528 | ||
531 | /* we are sending char from a workqueue so enable */ | 529 | /* we are sending char from a workqueue so enable */ |
532 | s->port.info->port.tty->low_latency = 1; | 530 | s->port.state->port.tty->low_latency = 1; |
533 | 531 | ||
534 | if (s->poll_time > 0) | 532 | if (s->poll_time > 0) |
535 | del_timer_sync(&s->timer); | 533 | del_timer_sync(&s->timer); |
@@ -925,3 +923,4 @@ module_exit(max3100_exit); | |||
925 | MODULE_DESCRIPTION("MAX3100 driver"); | 923 | MODULE_DESCRIPTION("MAX3100 driver"); |
926 | MODULE_AUTHOR("Christian Pellegrin <chripell@evolware.org>"); | 924 | MODULE_AUTHOR("Christian Pellegrin <chripell@evolware.org>"); |
927 | MODULE_LICENSE("GPL"); | 925 | MODULE_LICENSE("GPL"); |
926 | MODULE_ALIAS("spi:max3100"); | ||
diff --git a/drivers/serial/max3107-aava.c b/drivers/serial/max3107-aava.c new file mode 100644 index 000000000000..a1fe304f2f52 --- /dev/null +++ b/drivers/serial/max3107-aava.c | |||
@@ -0,0 +1,344 @@ | |||
1 | /* | ||
2 | * max3107.c - spi uart protocol driver for Maxim 3107 | ||
3 | * Based on max3100.c | ||
4 | * by Christian Pellegrin <chripell@evolware.org> | ||
5 | * and max3110.c | ||
6 | * by Feng Tang <feng.tang@intel.com> | ||
7 | * | ||
8 | * Copyright (C) Aavamobile 2009 | ||
9 | * | ||
10 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License as published by | ||
14 | * the Free Software Foundation; either version 2 of the License, or | ||
15 | * (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
25 | * | ||
26 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
27 | * | ||
28 | */ | ||
29 | |||
30 | #include <linux/delay.h> | ||
31 | #include <linux/device.h> | ||
32 | #include <linux/serial_core.h> | ||
33 | #include <linux/serial.h> | ||
34 | #include <linux/spi/spi.h> | ||
35 | #include <linux/freezer.h> | ||
36 | #include <linux/platform_device.h> | ||
37 | #include <linux/gpio.h> | ||
38 | #include <linux/sfi.h> | ||
39 | #include <asm/mrst.h> | ||
40 | #include "max3107.h" | ||
41 | |||
42 | /* GPIO direction to input function */ | ||
43 | static int max3107_gpio_direction_in(struct gpio_chip *chip, unsigned offset) | ||
44 | { | ||
45 | struct max3107_port *s = container_of(chip, struct max3107_port, chip); | ||
46 | u16 buf[1]; /* Buffer for SPI transfer */ | ||
47 | |||
48 | if (offset >= MAX3107_GPIO_COUNT) { | ||
49 | dev_err(&s->spi->dev, "Invalid GPIO\n"); | ||
50 | return -EINVAL; | ||
51 | } | ||
52 | |||
53 | /* Read current GPIO configuration register */ | ||
54 | buf[0] = MAX3107_GPIOCFG_REG; | ||
55 | /* Perform SPI transfer */ | ||
56 | if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 2)) { | ||
57 | dev_err(&s->spi->dev, "SPI transfer GPIO read failed\n"); | ||
58 | return -EIO; | ||
59 | } | ||
60 | buf[0] &= MAX3107_SPI_RX_DATA_MASK; | ||
61 | |||
62 | /* Set GPIO to input */ | ||
63 | buf[0] &= ~(0x0001 << offset); | ||
64 | |||
65 | /* Write new GPIO configuration register value */ | ||
66 | buf[0] |= (MAX3107_WRITE_BIT | MAX3107_GPIOCFG_REG); | ||
67 | /* Perform SPI transfer */ | ||
68 | if (max3107_rw(s, (u8 *)buf, NULL, 2)) { | ||
69 | dev_err(&s->spi->dev, "SPI transfer GPIO write failed\n"); | ||
70 | return -EIO; | ||
71 | } | ||
72 | return 0; | ||
73 | } | ||
74 | |||
75 | /* GPIO direction to output function */ | ||
76 | static int max3107_gpio_direction_out(struct gpio_chip *chip, unsigned offset, | ||
77 | int value) | ||
78 | { | ||
79 | struct max3107_port *s = container_of(chip, struct max3107_port, chip); | ||
80 | u16 buf[2]; /* Buffer for SPI transfers */ | ||
81 | |||
82 | if (offset >= MAX3107_GPIO_COUNT) { | ||
83 | dev_err(&s->spi->dev, "Invalid GPIO\n"); | ||
84 | return -EINVAL; | ||
85 | } | ||
86 | |||
87 | /* Read current GPIO configuration and data registers */ | ||
88 | buf[0] = MAX3107_GPIOCFG_REG; | ||
89 | buf[1] = MAX3107_GPIODATA_REG; | ||
90 | /* Perform SPI transfer */ | ||
91 | if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 4)) { | ||
92 | dev_err(&s->spi->dev, "SPI transfer gpio failed\n"); | ||
93 | return -EIO; | ||
94 | } | ||
95 | buf[0] &= MAX3107_SPI_RX_DATA_MASK; | ||
96 | buf[1] &= MAX3107_SPI_RX_DATA_MASK; | ||
97 | |||
98 | /* Set GPIO to output */ | ||
99 | buf[0] |= (0x0001 << offset); | ||
100 | /* Set value */ | ||
101 | if (value) | ||
102 | buf[1] |= (0x0001 << offset); | ||
103 | else | ||
104 | buf[1] &= ~(0x0001 << offset); | ||
105 | |||
106 | /* Write new GPIO configuration and data register values */ | ||
107 | buf[0] |= (MAX3107_WRITE_BIT | MAX3107_GPIOCFG_REG); | ||
108 | buf[1] |= (MAX3107_WRITE_BIT | MAX3107_GPIODATA_REG); | ||
109 | /* Perform SPI transfer */ | ||
110 | if (max3107_rw(s, (u8 *)buf, NULL, 4)) { | ||
111 | dev_err(&s->spi->dev, | ||
112 | "SPI transfer for GPIO conf data w failed\n"); | ||
113 | return -EIO; | ||
114 | } | ||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | /* GPIO value query function */ | ||
119 | static int max3107_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
120 | { | ||
121 | struct max3107_port *s = container_of(chip, struct max3107_port, chip); | ||
122 | u16 buf[1]; /* Buffer for SPI transfer */ | ||
123 | |||
124 | if (offset >= MAX3107_GPIO_COUNT) { | ||
125 | dev_err(&s->spi->dev, "Invalid GPIO\n"); | ||
126 | return -EINVAL; | ||
127 | } | ||
128 | |||
129 | /* Read current GPIO data register */ | ||
130 | buf[0] = MAX3107_GPIODATA_REG; | ||
131 | /* Perform SPI transfer */ | ||
132 | if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 2)) { | ||
133 | dev_err(&s->spi->dev, "SPI transfer GPIO data r failed\n"); | ||
134 | return -EIO; | ||
135 | } | ||
136 | buf[0] &= MAX3107_SPI_RX_DATA_MASK; | ||
137 | |||
138 | /* Return value */ | ||
139 | return buf[0] & (0x0001 << offset); | ||
140 | } | ||
141 | |||
142 | /* GPIO value set function */ | ||
143 | static void max3107_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
144 | { | ||
145 | struct max3107_port *s = container_of(chip, struct max3107_port, chip); | ||
146 | u16 buf[2]; /* Buffer for SPI transfers */ | ||
147 | |||
148 | if (offset >= MAX3107_GPIO_COUNT) { | ||
149 | dev_err(&s->spi->dev, "Invalid GPIO\n"); | ||
150 | return; | ||
151 | } | ||
152 | |||
153 | /* Read current GPIO configuration registers*/ | ||
154 | buf[0] = MAX3107_GPIODATA_REG; | ||
155 | buf[1] = MAX3107_GPIOCFG_REG; | ||
156 | /* Perform SPI transfer */ | ||
157 | if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 4)) { | ||
158 | dev_err(&s->spi->dev, | ||
159 | "SPI transfer for GPIO data and config read failed\n"); | ||
160 | return; | ||
161 | } | ||
162 | buf[0] &= MAX3107_SPI_RX_DATA_MASK; | ||
163 | buf[1] &= MAX3107_SPI_RX_DATA_MASK; | ||
164 | |||
165 | if (!(buf[1] & (0x0001 << offset))) { | ||
166 | /* Configured as input, can't set value */ | ||
167 | dev_warn(&s->spi->dev, | ||
168 | "Trying to set value for input GPIO\n"); | ||
169 | return; | ||
170 | } | ||
171 | |||
172 | /* Set value */ | ||
173 | if (value) | ||
174 | buf[0] |= (0x0001 << offset); | ||
175 | else | ||
176 | buf[0] &= ~(0x0001 << offset); | ||
177 | |||
178 | /* Write new GPIO data register value */ | ||
179 | buf[0] |= (MAX3107_WRITE_BIT | MAX3107_GPIODATA_REG); | ||
180 | /* Perform SPI transfer */ | ||
181 | if (max3107_rw(s, (u8 *)buf, NULL, 2)) | ||
182 | dev_err(&s->spi->dev, "SPI transfer GPIO data w failed\n"); | ||
183 | } | ||
184 | |||
185 | /* GPIO chip data */ | ||
186 | static struct gpio_chip max3107_gpio_chip = { | ||
187 | .owner = THIS_MODULE, | ||
188 | .direction_input = max3107_gpio_direction_in, | ||
189 | .direction_output = max3107_gpio_direction_out, | ||
190 | .get = max3107_gpio_get, | ||
191 | .set = max3107_gpio_set, | ||
192 | .can_sleep = 1, | ||
193 | .base = MAX3107_GPIO_BASE, | ||
194 | .ngpio = MAX3107_GPIO_COUNT, | ||
195 | }; | ||
196 | |||
197 | /** | ||
198 | * max3107_aava_reset - reset on AAVA systems | ||
199 | * @spi: The SPI device we are probing | ||
200 | * | ||
201 | * Reset the device ready for probing. | ||
202 | */ | ||
203 | |||
204 | static int max3107_aava_reset(struct spi_device *spi) | ||
205 | { | ||
206 | /* Reset the chip */ | ||
207 | if (gpio_request(MAX3107_RESET_GPIO, "max3107")) { | ||
208 | pr_err("Requesting RESET GPIO failed\n"); | ||
209 | return -EIO; | ||
210 | } | ||
211 | if (gpio_direction_output(MAX3107_RESET_GPIO, 0)) { | ||
212 | pr_err("Setting RESET GPIO to 0 failed\n"); | ||
213 | gpio_free(MAX3107_RESET_GPIO); | ||
214 | return -EIO; | ||
215 | } | ||
216 | msleep(MAX3107_RESET_DELAY); | ||
217 | if (gpio_direction_output(MAX3107_RESET_GPIO, 1)) { | ||
218 | pr_err("Setting RESET GPIO to 1 failed\n"); | ||
219 | gpio_free(MAX3107_RESET_GPIO); | ||
220 | return -EIO; | ||
221 | } | ||
222 | gpio_free(MAX3107_RESET_GPIO); | ||
223 | msleep(MAX3107_WAKEUP_DELAY); | ||
224 | return 0; | ||
225 | } | ||
226 | |||
227 | static int max3107_aava_configure(struct max3107_port *s) | ||
228 | { | ||
229 | int retval; | ||
230 | |||
231 | /* Initialize GPIO chip data */ | ||
232 | s->chip = max3107_gpio_chip; | ||
233 | s->chip.label = s->spi->modalias; | ||
234 | s->chip.dev = &s->spi->dev; | ||
235 | |||
236 | /* Add GPIO chip */ | ||
237 | retval = gpiochip_add(&s->chip); | ||
238 | if (retval) { | ||
239 | dev_err(&s->spi->dev, "Adding GPIO chip failed\n"); | ||
240 | return retval; | ||
241 | } | ||
242 | |||
243 | /* Temporary fix for EV2 boot problems, set modem reset to 0 */ | ||
244 | max3107_gpio_direction_out(&s->chip, 3, 0); | ||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | #if 0 | ||
249 | /* This will get enabled once we have the board stuff merged for this | ||
250 | specific case */ | ||
251 | |||
252 | static const struct baud_table brg13_ext[] = { | ||
253 | { 300, MAX3107_BRG13_B300 }, | ||
254 | { 600, MAX3107_BRG13_B600 }, | ||
255 | { 1200, MAX3107_BRG13_B1200 }, | ||
256 | { 2400, MAX3107_BRG13_B2400 }, | ||
257 | { 4800, MAX3107_BRG13_B4800 }, | ||
258 | { 9600, MAX3107_BRG13_B9600 }, | ||
259 | { 19200, MAX3107_BRG13_B19200 }, | ||
260 | { 57600, MAX3107_BRG13_B57600 }, | ||
261 | { 115200, MAX3107_BRG13_B115200 }, | ||
262 | { 230400, MAX3107_BRG13_B230400 }, | ||
263 | { 460800, MAX3107_BRG13_B460800 }, | ||
264 | { 921600, MAX3107_BRG13_B921600 }, | ||
265 | { 0, 0 } | ||
266 | }; | ||
267 | |||
268 | static void max3107_aava_init(struct max3107_port *s) | ||
269 | { | ||
270 | /*override for AAVA SC specific*/ | ||
271 | if (mrst_platform_id() == MRST_PLATFORM_AAVA_SC) { | ||
272 | if (get_koski_build_id() <= KOSKI_EV2) | ||
273 | if (s->ext_clk) { | ||
274 | s->brg_cfg = MAX3107_BRG13_B9600; | ||
275 | s->baud_tbl = (struct baud_table *)brg13_ext; | ||
276 | } | ||
277 | } | ||
278 | } | ||
279 | #endif | ||
280 | |||
281 | static int __devexit max3107_aava_remove(struct spi_device *spi) | ||
282 | { | ||
283 | struct max3107_port *s = dev_get_drvdata(&spi->dev); | ||
284 | |||
285 | /* Remove GPIO chip */ | ||
286 | if (gpiochip_remove(&s->chip)) | ||
287 | dev_warn(&spi->dev, "Removing GPIO chip failed\n"); | ||
288 | |||
289 | /* Then do the default remove */ | ||
290 | return max3107_remove(spi); | ||
291 | } | ||
292 | |||
293 | /* Platform data */ | ||
294 | static struct max3107_plat aava_plat_data = { | ||
295 | .loopback = 0, | ||
296 | .ext_clk = 1, | ||
297 | /* .init = max3107_aava_init, */ | ||
298 | .configure = max3107_aava_configure, | ||
299 | .hw_suspend = max3107_hw_susp, | ||
300 | .polled_mode = 0, | ||
301 | .poll_time = 0, | ||
302 | }; | ||
303 | |||
304 | |||
305 | static int __devinit max3107_probe_aava(struct spi_device *spi) | ||
306 | { | ||
307 | int err = max3107_aava_reset(spi); | ||
308 | if (err < 0) | ||
309 | return err; | ||
310 | return max3107_probe(spi, &aava_plat_data); | ||
311 | } | ||
312 | |||
313 | /* Spi driver data */ | ||
314 | static struct spi_driver max3107_driver = { | ||
315 | .driver = { | ||
316 | .name = "aava-max3107", | ||
317 | .bus = &spi_bus_type, | ||
318 | .owner = THIS_MODULE, | ||
319 | }, | ||
320 | .probe = max3107_probe_aava, | ||
321 | .remove = __devexit_p(max3107_aava_remove), | ||
322 | .suspend = max3107_suspend, | ||
323 | .resume = max3107_resume, | ||
324 | }; | ||
325 | |||
326 | /* Driver init function */ | ||
327 | static int __init max3107_init(void) | ||
328 | { | ||
329 | return spi_register_driver(&max3107_driver); | ||
330 | } | ||
331 | |||
332 | /* Driver exit function */ | ||
333 | static void __exit max3107_exit(void) | ||
334 | { | ||
335 | spi_unregister_driver(&max3107_driver); | ||
336 | } | ||
337 | |||
338 | module_init(max3107_init); | ||
339 | module_exit(max3107_exit); | ||
340 | |||
341 | MODULE_DESCRIPTION("MAX3107 driver"); | ||
342 | MODULE_AUTHOR("Aavamobile"); | ||
343 | MODULE_ALIAS("aava-max3107-spi"); | ||
344 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/serial/max3107.c b/drivers/serial/max3107.c new file mode 100644 index 000000000000..910870edf708 --- /dev/null +++ b/drivers/serial/max3107.c | |||
@@ -0,0 +1,1213 @@ | |||
1 | /* | ||
2 | * max3107.c - spi uart protocol driver for Maxim 3107 | ||
3 | * Based on max3100.c | ||
4 | * by Christian Pellegrin <chripell@evolware.org> | ||
5 | * and max3110.c | ||
6 | * by Feng Tang <feng.tang@intel.com> | ||
7 | * | ||
8 | * Copyright (C) Aavamobile 2009 | ||
9 | * | ||
10 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License as published by | ||
14 | * the Free Software Foundation; either version 2 of the License, or | ||
15 | * (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
25 | * | ||
26 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
27 | * | ||
28 | */ | ||
29 | |||
30 | #include <linux/delay.h> | ||
31 | #include <linux/device.h> | ||
32 | #include <linux/serial_core.h> | ||
33 | #include <linux/serial.h> | ||
34 | #include <linux/gpio.h> | ||
35 | #include <linux/spi/spi.h> | ||
36 | #include <linux/freezer.h> | ||
37 | #include "max3107.h" | ||
38 | |||
39 | static const struct baud_table brg26_ext[] = { | ||
40 | { 300, MAX3107_BRG26_B300 }, | ||
41 | { 600, MAX3107_BRG26_B600 }, | ||
42 | { 1200, MAX3107_BRG26_B1200 }, | ||
43 | { 2400, MAX3107_BRG26_B2400 }, | ||
44 | { 4800, MAX3107_BRG26_B4800 }, | ||
45 | { 9600, MAX3107_BRG26_B9600 }, | ||
46 | { 19200, MAX3107_BRG26_B19200 }, | ||
47 | { 57600, MAX3107_BRG26_B57600 }, | ||
48 | { 115200, MAX3107_BRG26_B115200 }, | ||
49 | { 230400, MAX3107_BRG26_B230400 }, | ||
50 | { 460800, MAX3107_BRG26_B460800 }, | ||
51 | { 921600, MAX3107_BRG26_B921600 }, | ||
52 | { 0, 0 } | ||
53 | }; | ||
54 | |||
55 | static const struct baud_table brg13_int[] = { | ||
56 | { 300, MAX3107_BRG13_IB300 }, | ||
57 | { 600, MAX3107_BRG13_IB600 }, | ||
58 | { 1200, MAX3107_BRG13_IB1200 }, | ||
59 | { 2400, MAX3107_BRG13_IB2400 }, | ||
60 | { 4800, MAX3107_BRG13_IB4800 }, | ||
61 | { 9600, MAX3107_BRG13_IB9600 }, | ||
62 | { 19200, MAX3107_BRG13_IB19200 }, | ||
63 | { 57600, MAX3107_BRG13_IB57600 }, | ||
64 | { 115200, MAX3107_BRG13_IB115200 }, | ||
65 | { 230400, MAX3107_BRG13_IB230400 }, | ||
66 | { 460800, MAX3107_BRG13_IB460800 }, | ||
67 | { 921600, MAX3107_BRG13_IB921600 }, | ||
68 | { 0, 0 } | ||
69 | }; | ||
70 | |||
71 | static u32 get_new_brg(int baud, struct max3107_port *s) | ||
72 | { | ||
73 | int i; | ||
74 | const struct baud_table *baud_tbl = s->baud_tbl; | ||
75 | |||
76 | for (i = 0; i < 13; i++) { | ||
77 | if (baud == baud_tbl[i].baud) | ||
78 | return baud_tbl[i].new_brg; | ||
79 | } | ||
80 | |||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | /* Perform SPI transfer for write/read of device register(s) */ | ||
85 | int max3107_rw(struct max3107_port *s, u8 *tx, u8 *rx, int len) | ||
86 | { | ||
87 | struct spi_message spi_msg; | ||
88 | struct spi_transfer spi_xfer; | ||
89 | |||
90 | /* Initialize SPI ,message */ | ||
91 | spi_message_init(&spi_msg); | ||
92 | |||
93 | /* Initialize SPI transfer */ | ||
94 | memset(&spi_xfer, 0, sizeof spi_xfer); | ||
95 | spi_xfer.len = len; | ||
96 | spi_xfer.tx_buf = tx; | ||
97 | spi_xfer.rx_buf = rx; | ||
98 | spi_xfer.speed_hz = MAX3107_SPI_SPEED; | ||
99 | |||
100 | /* Add SPI transfer to SPI message */ | ||
101 | spi_message_add_tail(&spi_xfer, &spi_msg); | ||
102 | |||
103 | #ifdef DBG_TRACE_SPI_DATA | ||
104 | { | ||
105 | int i; | ||
106 | pr_info("tx len %d:\n", spi_xfer.len); | ||
107 | for (i = 0 ; i < spi_xfer.len && i < 32 ; i++) | ||
108 | pr_info(" %x", ((u8 *)spi_xfer.tx_buf)[i]); | ||
109 | pr_info("\n"); | ||
110 | } | ||
111 | #endif | ||
112 | |||
113 | /* Perform synchronous SPI transfer */ | ||
114 | if (spi_sync(s->spi, &spi_msg)) { | ||
115 | dev_err(&s->spi->dev, "spi_sync failure\n"); | ||
116 | return -EIO; | ||
117 | } | ||
118 | |||
119 | #ifdef DBG_TRACE_SPI_DATA | ||
120 | if (spi_xfer.rx_buf) { | ||
121 | int i; | ||
122 | pr_info("rx len %d:\n", spi_xfer.len); | ||
123 | for (i = 0 ; i < spi_xfer.len && i < 32 ; i++) | ||
124 | pr_info(" %x", ((u8 *)spi_xfer.rx_buf)[i]); | ||
125 | pr_info("\n"); | ||
126 | } | ||
127 | #endif | ||
128 | return 0; | ||
129 | } | ||
130 | EXPORT_SYMBOL_GPL(max3107_rw); | ||
131 | |||
132 | /* Puts received data to circular buffer */ | ||
133 | static void put_data_to_circ_buf(struct max3107_port *s, unsigned char *data, | ||
134 | int len) | ||
135 | { | ||
136 | struct uart_port *port = &s->port; | ||
137 | struct tty_struct *tty; | ||
138 | |||
139 | if (!port->state) | ||
140 | return; | ||
141 | |||
142 | tty = port->state->port.tty; | ||
143 | if (!tty) | ||
144 | return; | ||
145 | |||
146 | /* Insert received data */ | ||
147 | tty_insert_flip_string(tty, data, len); | ||
148 | /* Update RX counter */ | ||
149 | port->icount.rx += len; | ||
150 | } | ||
151 | |||
152 | /* Handle data receiving */ | ||
153 | static void max3107_handlerx(struct max3107_port *s, u16 rxlvl) | ||
154 | { | ||
155 | int i; | ||
156 | int j; | ||
157 | int len; /* SPI transfer buffer length */ | ||
158 | u16 *buf; | ||
159 | u8 *valid_str; | ||
160 | |||
161 | if (!s->rx_enabled) | ||
162 | /* RX is disabled */ | ||
163 | return; | ||
164 | |||
165 | if (rxlvl == 0) { | ||
166 | /* RX fifo is empty */ | ||
167 | return; | ||
168 | } else if (rxlvl >= MAX3107_RX_FIFO_SIZE) { | ||
169 | dev_warn(&s->spi->dev, "Possible RX FIFO overrun %d\n", rxlvl); | ||
170 | /* Ensure sanity of RX level */ | ||
171 | rxlvl = MAX3107_RX_FIFO_SIZE; | ||
172 | } | ||
173 | if ((s->rxbuf == 0) || (s->rxstr == 0)) { | ||
174 | dev_warn(&s->spi->dev, "Rx buffer/str isn't ready\n"); | ||
175 | return; | ||
176 | } | ||
177 | buf = s->rxbuf; | ||
178 | valid_str = s->rxstr; | ||
179 | while (rxlvl) { | ||
180 | pr_debug("rxlvl %d\n", rxlvl); | ||
181 | /* Clear buffer */ | ||
182 | memset(buf, 0, sizeof(u16) * (MAX3107_RX_FIFO_SIZE + 2)); | ||
183 | len = 0; | ||
184 | if (s->irqen_reg & MAX3107_IRQ_RXFIFO_BIT) { | ||
185 | /* First disable RX FIFO interrupt */ | ||
186 | pr_debug("Disabling RX INT\n"); | ||
187 | buf[0] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG); | ||
188 | s->irqen_reg &= ~MAX3107_IRQ_RXFIFO_BIT; | ||
189 | buf[0] |= s->irqen_reg; | ||
190 | len++; | ||
191 | } | ||
192 | /* Just increase the length by amount of words in FIFO since | ||
193 | * buffer was zeroed and SPI transfer of 0x0000 means reading | ||
194 | * from RX FIFO | ||
195 | */ | ||
196 | len += rxlvl; | ||
197 | /* Append RX level query */ | ||
198 | buf[len] = MAX3107_RXFIFOLVL_REG; | ||
199 | len++; | ||
200 | |||
201 | /* Perform the SPI transfer */ | ||
202 | if (max3107_rw(s, (u8 *)buf, (u8 *)buf, len * 2)) { | ||
203 | dev_err(&s->spi->dev, "SPI transfer for RX h failed\n"); | ||
204 | return; | ||
205 | } | ||
206 | |||
207 | /* Skip RX FIFO interrupt disabling word if it was added */ | ||
208 | j = ((len - 1) - rxlvl); | ||
209 | /* Read received words */ | ||
210 | for (i = 0; i < rxlvl; i++, j++) | ||
211 | valid_str[i] = (u8)buf[j]; | ||
212 | put_data_to_circ_buf(s, valid_str, rxlvl); | ||
213 | /* Get new RX level */ | ||
214 | rxlvl = (buf[len - 1] & MAX3107_SPI_RX_DATA_MASK); | ||
215 | } | ||
216 | |||
217 | if (s->rx_enabled) { | ||
218 | /* RX still enabled, re-enable RX FIFO interrupt */ | ||
219 | pr_debug("Enabling RX INT\n"); | ||
220 | buf[0] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG); | ||
221 | s->irqen_reg |= MAX3107_IRQ_RXFIFO_BIT; | ||
222 | buf[0] |= s->irqen_reg; | ||
223 | if (max3107_rw(s, (u8 *)buf, NULL, 2)) | ||
224 | dev_err(&s->spi->dev, "RX FIFO INT enabling failed\n"); | ||
225 | } | ||
226 | |||
227 | /* Push the received data to receivers */ | ||
228 | if (s->port.state->port.tty) | ||
229 | tty_flip_buffer_push(s->port.state->port.tty); | ||
230 | } | ||
231 | |||
232 | |||
233 | /* Handle data sending */ | ||
234 | static void max3107_handletx(struct max3107_port *s) | ||
235 | { | ||
236 | struct circ_buf *xmit = &s->port.state->xmit; | ||
237 | int i; | ||
238 | unsigned long flags; | ||
239 | int len; /* SPI transfer buffer length */ | ||
240 | u16 *buf; | ||
241 | |||
242 | if (!s->tx_fifo_empty) | ||
243 | /* Don't send more data before previous data is sent */ | ||
244 | return; | ||
245 | |||
246 | if (uart_circ_empty(xmit) || uart_tx_stopped(&s->port)) | ||
247 | /* No data to send or TX is stopped */ | ||
248 | return; | ||
249 | |||
250 | if (!s->txbuf) { | ||
251 | dev_warn(&s->spi->dev, "Txbuf isn't ready\n"); | ||
252 | return; | ||
253 | } | ||
254 | buf = s->txbuf; | ||
255 | /* Get length of data pending in circular buffer */ | ||
256 | len = uart_circ_chars_pending(xmit); | ||
257 | if (len) { | ||
258 | /* Limit to size of TX FIFO */ | ||
259 | if (len > MAX3107_TX_FIFO_SIZE) | ||
260 | len = MAX3107_TX_FIFO_SIZE; | ||
261 | |||
262 | pr_debug("txlen %d\n", len); | ||
263 | |||
264 | /* Update TX counter */ | ||
265 | s->port.icount.tx += len; | ||
266 | |||
267 | /* TX FIFO will no longer be empty */ | ||
268 | s->tx_fifo_empty = 0; | ||
269 | |||
270 | i = 0; | ||
271 | if (s->irqen_reg & MAX3107_IRQ_TXEMPTY_BIT) { | ||
272 | /* First disable TX empty interrupt */ | ||
273 | pr_debug("Disabling TE INT\n"); | ||
274 | buf[i] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG); | ||
275 | s->irqen_reg &= ~MAX3107_IRQ_TXEMPTY_BIT; | ||
276 | buf[i] |= s->irqen_reg; | ||
277 | i++; | ||
278 | len++; | ||
279 | } | ||
280 | /* Add data to send */ | ||
281 | spin_lock_irqsave(&s->port.lock, flags); | ||
282 | for ( ; i < len ; i++) { | ||
283 | buf[i] = (MAX3107_WRITE_BIT | MAX3107_THR_REG); | ||
284 | buf[i] |= ((u16)xmit->buf[xmit->tail] & | ||
285 | MAX3107_SPI_TX_DATA_MASK); | ||
286 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
287 | } | ||
288 | spin_unlock_irqrestore(&s->port.lock, flags); | ||
289 | if (!(s->irqen_reg & MAX3107_IRQ_TXEMPTY_BIT)) { | ||
290 | /* Enable TX empty interrupt */ | ||
291 | pr_debug("Enabling TE INT\n"); | ||
292 | buf[i] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG); | ||
293 | s->irqen_reg |= MAX3107_IRQ_TXEMPTY_BIT; | ||
294 | buf[i] |= s->irqen_reg; | ||
295 | i++; | ||
296 | len++; | ||
297 | } | ||
298 | if (!s->tx_enabled) { | ||
299 | /* Enable TX */ | ||
300 | pr_debug("Enable TX\n"); | ||
301 | buf[i] = (MAX3107_WRITE_BIT | MAX3107_MODE1_REG); | ||
302 | spin_lock_irqsave(&s->data_lock, flags); | ||
303 | s->mode1_reg &= ~MAX3107_MODE1_TXDIS_BIT; | ||
304 | buf[i] |= s->mode1_reg; | ||
305 | spin_unlock_irqrestore(&s->data_lock, flags); | ||
306 | s->tx_enabled = 1; | ||
307 | i++; | ||
308 | len++; | ||
309 | } | ||
310 | |||
311 | /* Perform the SPI transfer */ | ||
312 | if (max3107_rw(s, (u8 *)buf, NULL, len*2)) { | ||
313 | dev_err(&s->spi->dev, | ||
314 | "SPI transfer TX handling failed\n"); | ||
315 | return; | ||
316 | } | ||
317 | } | ||
318 | |||
319 | /* Indicate wake up if circular buffer is getting low on data */ | ||
320 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
321 | uart_write_wakeup(&s->port); | ||
322 | |||
323 | } | ||
324 | |||
325 | /* Handle interrupts | ||
326 | * Also reads and returns current RX FIFO level | ||
327 | */ | ||
328 | static u16 handle_interrupt(struct max3107_port *s) | ||
329 | { | ||
330 | u16 buf[4]; /* Buffer for SPI transfers */ | ||
331 | u8 irq_status; | ||
332 | u16 rx_level; | ||
333 | unsigned long flags; | ||
334 | |||
335 | /* Read IRQ status register */ | ||
336 | buf[0] = MAX3107_IRQSTS_REG; | ||
337 | /* Read status IRQ status register */ | ||
338 | buf[1] = MAX3107_STS_IRQSTS_REG; | ||
339 | /* Read LSR IRQ status register */ | ||
340 | buf[2] = MAX3107_LSR_IRQSTS_REG; | ||
341 | /* Query RX level */ | ||
342 | buf[3] = MAX3107_RXFIFOLVL_REG; | ||
343 | |||
344 | if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 8)) { | ||
345 | dev_err(&s->spi->dev, | ||
346 | "SPI transfer for INTR handling failed\n"); | ||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | irq_status = (u8)buf[0]; | ||
351 | pr_debug("IRQSTS %x\n", irq_status); | ||
352 | rx_level = (buf[3] & MAX3107_SPI_RX_DATA_MASK); | ||
353 | |||
354 | if (irq_status & MAX3107_IRQ_LSR_BIT) { | ||
355 | /* LSR interrupt */ | ||
356 | if (buf[2] & MAX3107_LSR_RXTO_BIT) | ||
357 | /* RX timeout interrupt, | ||
358 | * handled by normal RX handling | ||
359 | */ | ||
360 | pr_debug("RX TO INT\n"); | ||
361 | } | ||
362 | |||
363 | if (irq_status & MAX3107_IRQ_TXEMPTY_BIT) { | ||
364 | /* Tx empty interrupt, | ||
365 | * disable TX and set tx_fifo_empty flag | ||
366 | */ | ||
367 | pr_debug("TE INT, disabling TX\n"); | ||
368 | buf[0] = (MAX3107_WRITE_BIT | MAX3107_MODE1_REG); | ||
369 | spin_lock_irqsave(&s->data_lock, flags); | ||
370 | s->mode1_reg |= MAX3107_MODE1_TXDIS_BIT; | ||
371 | buf[0] |= s->mode1_reg; | ||
372 | spin_unlock_irqrestore(&s->data_lock, flags); | ||
373 | if (max3107_rw(s, (u8 *)buf, NULL, 2)) | ||
374 | dev_err(&s->spi->dev, "SPI transfer TX dis failed\n"); | ||
375 | s->tx_enabled = 0; | ||
376 | s->tx_fifo_empty = 1; | ||
377 | } | ||
378 | |||
379 | if (irq_status & MAX3107_IRQ_RXFIFO_BIT) | ||
380 | /* RX FIFO interrupt, | ||
381 | * handled by normal RX handling | ||
382 | */ | ||
383 | pr_debug("RFIFO INT\n"); | ||
384 | |||
385 | /* Return RX level */ | ||
386 | return rx_level; | ||
387 | } | ||
388 | |||
389 | /* Trigger work thread*/ | ||
390 | static void max3107_dowork(struct max3107_port *s) | ||
391 | { | ||
392 | if (!work_pending(&s->work) && !freezing(current) && !s->suspended) | ||
393 | queue_work(s->workqueue, &s->work); | ||
394 | else | ||
395 | dev_warn(&s->spi->dev, "interrup isn't serviced normally!\n"); | ||
396 | } | ||
397 | |||
398 | /* Work thread */ | ||
399 | static void max3107_work(struct work_struct *w) | ||
400 | { | ||
401 | struct max3107_port *s = container_of(w, struct max3107_port, work); | ||
402 | u16 rxlvl = 0; | ||
403 | int len; /* SPI transfer buffer length */ | ||
404 | u16 buf[5]; /* Buffer for SPI transfers */ | ||
405 | unsigned long flags; | ||
406 | |||
407 | /* Start by reading current RX FIFO level */ | ||
408 | buf[0] = MAX3107_RXFIFOLVL_REG; | ||
409 | if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 2)) { | ||
410 | dev_err(&s->spi->dev, "SPI transfer RX lev failed\n"); | ||
411 | rxlvl = 0; | ||
412 | } else { | ||
413 | rxlvl = (buf[0] & MAX3107_SPI_RX_DATA_MASK); | ||
414 | } | ||
415 | |||
416 | do { | ||
417 | pr_debug("rxlvl %d\n", rxlvl); | ||
418 | |||
419 | /* Handle RX */ | ||
420 | max3107_handlerx(s, rxlvl); | ||
421 | rxlvl = 0; | ||
422 | |||
423 | if (s->handle_irq) { | ||
424 | /* Handle pending interrupts | ||
425 | * We also get new RX FIFO level since new data may | ||
426 | * have been received while pushing received data to | ||
427 | * receivers | ||
428 | */ | ||
429 | s->handle_irq = 0; | ||
430 | rxlvl = handle_interrupt(s); | ||
431 | } | ||
432 | |||
433 | /* Handle TX */ | ||
434 | max3107_handletx(s); | ||
435 | |||
436 | /* Handle configuration changes */ | ||
437 | len = 0; | ||
438 | spin_lock_irqsave(&s->data_lock, flags); | ||
439 | if (s->mode1_commit) { | ||
440 | pr_debug("mode1_commit\n"); | ||
441 | buf[len] = (MAX3107_WRITE_BIT | MAX3107_MODE1_REG); | ||
442 | buf[len++] |= s->mode1_reg; | ||
443 | s->mode1_commit = 0; | ||
444 | } | ||
445 | if (s->lcr_commit) { | ||
446 | pr_debug("lcr_commit\n"); | ||
447 | buf[len] = (MAX3107_WRITE_BIT | MAX3107_LCR_REG); | ||
448 | buf[len++] |= s->lcr_reg; | ||
449 | s->lcr_commit = 0; | ||
450 | } | ||
451 | if (s->brg_commit) { | ||
452 | pr_debug("brg_commit\n"); | ||
453 | buf[len] = (MAX3107_WRITE_BIT | MAX3107_BRGDIVMSB_REG); | ||
454 | buf[len++] |= ((s->brg_cfg >> 16) & | ||
455 | MAX3107_SPI_TX_DATA_MASK); | ||
456 | buf[len] = (MAX3107_WRITE_BIT | MAX3107_BRGDIVLSB_REG); | ||
457 | buf[len++] |= ((s->brg_cfg >> 8) & | ||
458 | MAX3107_SPI_TX_DATA_MASK); | ||
459 | buf[len] = (MAX3107_WRITE_BIT | MAX3107_BRGCFG_REG); | ||
460 | buf[len++] |= ((s->brg_cfg) & 0xff); | ||
461 | s->brg_commit = 0; | ||
462 | } | ||
463 | spin_unlock_irqrestore(&s->data_lock, flags); | ||
464 | |||
465 | if (len > 0) { | ||
466 | if (max3107_rw(s, (u8 *)buf, NULL, len * 2)) | ||
467 | dev_err(&s->spi->dev, | ||
468 | "SPI transfer config failed\n"); | ||
469 | } | ||
470 | |||
471 | /* Reloop if interrupt handling indicated data in RX FIFO */ | ||
472 | } while (rxlvl); | ||
473 | |||
474 | } | ||
475 | |||
476 | /* Set sleep mode */ | ||
477 | static void max3107_set_sleep(struct max3107_port *s, int mode) | ||
478 | { | ||
479 | u16 buf[1]; /* Buffer for SPI transfer */ | ||
480 | unsigned long flags; | ||
481 | pr_debug("enter, mode %d\n", mode); | ||
482 | |||
483 | buf[0] = (MAX3107_WRITE_BIT | MAX3107_MODE1_REG); | ||
484 | spin_lock_irqsave(&s->data_lock, flags); | ||
485 | switch (mode) { | ||
486 | case MAX3107_DISABLE_FORCED_SLEEP: | ||
487 | s->mode1_reg &= ~MAX3107_MODE1_FORCESLEEP_BIT; | ||
488 | break; | ||
489 | case MAX3107_ENABLE_FORCED_SLEEP: | ||
490 | s->mode1_reg |= MAX3107_MODE1_FORCESLEEP_BIT; | ||
491 | break; | ||
492 | case MAX3107_DISABLE_AUTOSLEEP: | ||
493 | s->mode1_reg &= ~MAX3107_MODE1_AUTOSLEEP_BIT; | ||
494 | break; | ||
495 | case MAX3107_ENABLE_AUTOSLEEP: | ||
496 | s->mode1_reg |= MAX3107_MODE1_AUTOSLEEP_BIT; | ||
497 | break; | ||
498 | default: | ||
499 | spin_unlock_irqrestore(&s->data_lock, flags); | ||
500 | dev_warn(&s->spi->dev, "invalid sleep mode\n"); | ||
501 | return; | ||
502 | } | ||
503 | buf[0] |= s->mode1_reg; | ||
504 | spin_unlock_irqrestore(&s->data_lock, flags); | ||
505 | |||
506 | if (max3107_rw(s, (u8 *)buf, NULL, 2)) | ||
507 | dev_err(&s->spi->dev, "SPI transfer sleep mode failed\n"); | ||
508 | |||
509 | if (mode == MAX3107_DISABLE_AUTOSLEEP || | ||
510 | mode == MAX3107_DISABLE_FORCED_SLEEP) | ||
511 | msleep(MAX3107_WAKEUP_DELAY); | ||
512 | } | ||
513 | |||
514 | /* Perform full register initialization */ | ||
515 | static void max3107_register_init(struct max3107_port *s) | ||
516 | { | ||
517 | u16 buf[11]; /* Buffer for SPI transfers */ | ||
518 | |||
519 | /* 1. Configure baud rate, 9600 as default */ | ||
520 | s->baud = 9600; | ||
521 | /* the below is default*/ | ||
522 | if (s->ext_clk) { | ||
523 | s->brg_cfg = MAX3107_BRG26_B9600; | ||
524 | s->baud_tbl = (struct baud_table *)brg26_ext; | ||
525 | } else { | ||
526 | s->brg_cfg = MAX3107_BRG13_IB9600; | ||
527 | s->baud_tbl = (struct baud_table *)brg13_int; | ||
528 | } | ||
529 | |||
530 | if (s->pdata->init) | ||
531 | s->pdata->init(s); | ||
532 | |||
533 | buf[0] = (MAX3107_WRITE_BIT | MAX3107_BRGDIVMSB_REG) | ||
534 | | ((s->brg_cfg >> 16) & MAX3107_SPI_TX_DATA_MASK); | ||
535 | buf[1] = (MAX3107_WRITE_BIT | MAX3107_BRGDIVLSB_REG) | ||
536 | | ((s->brg_cfg >> 8) & MAX3107_SPI_TX_DATA_MASK); | ||
537 | buf[2] = (MAX3107_WRITE_BIT | MAX3107_BRGCFG_REG) | ||
538 | | ((s->brg_cfg) & 0xff); | ||
539 | |||
540 | /* 2. Configure LCR register, 8N1 mode by default */ | ||
541 | s->lcr_reg = MAX3107_LCR_WORD_LEN_8; | ||
542 | buf[3] = (MAX3107_WRITE_BIT | MAX3107_LCR_REG) | ||
543 | | s->lcr_reg; | ||
544 | |||
545 | /* 3. Configure MODE 1 register */ | ||
546 | s->mode1_reg = 0; | ||
547 | /* Enable IRQ pin */ | ||
548 | s->mode1_reg |= MAX3107_MODE1_IRQSEL_BIT; | ||
549 | /* Disable TX */ | ||
550 | s->mode1_reg |= MAX3107_MODE1_TXDIS_BIT; | ||
551 | s->tx_enabled = 0; | ||
552 | /* RX is enabled */ | ||
553 | s->rx_enabled = 1; | ||
554 | buf[4] = (MAX3107_WRITE_BIT | MAX3107_MODE1_REG) | ||
555 | | s->mode1_reg; | ||
556 | |||
557 | /* 4. Configure MODE 2 register */ | ||
558 | buf[5] = (MAX3107_WRITE_BIT | MAX3107_MODE2_REG); | ||
559 | if (s->loopback) { | ||
560 | /* Enable loopback */ | ||
561 | buf[5] |= MAX3107_MODE2_LOOPBACK_BIT; | ||
562 | } | ||
563 | /* Reset FIFOs */ | ||
564 | buf[5] |= MAX3107_MODE2_FIFORST_BIT; | ||
565 | s->tx_fifo_empty = 1; | ||
566 | |||
567 | /* 5. Configure FIFO trigger level register */ | ||
568 | buf[6] = (MAX3107_WRITE_BIT | MAX3107_FIFOTRIGLVL_REG); | ||
569 | /* RX FIFO trigger for 16 words, TX FIFO trigger not used */ | ||
570 | buf[6] |= (MAX3107_FIFOTRIGLVL_RX(16) | MAX3107_FIFOTRIGLVL_TX(0)); | ||
571 | |||
572 | /* 6. Configure flow control levels */ | ||
573 | buf[7] = (MAX3107_WRITE_BIT | MAX3107_FLOWLVL_REG); | ||
574 | /* Flow control halt level 96, resume level 48 */ | ||
575 | buf[7] |= (MAX3107_FLOWLVL_RES(48) | MAX3107_FLOWLVL_HALT(96)); | ||
576 | |||
577 | /* 7. Configure flow control */ | ||
578 | buf[8] = (MAX3107_WRITE_BIT | MAX3107_FLOWCTRL_REG); | ||
579 | /* Enable auto CTS and auto RTS flow control */ | ||
580 | buf[8] |= (MAX3107_FLOWCTRL_AUTOCTS_BIT | MAX3107_FLOWCTRL_AUTORTS_BIT); | ||
581 | |||
582 | /* 8. Configure RX timeout register */ | ||
583 | buf[9] = (MAX3107_WRITE_BIT | MAX3107_RXTO_REG); | ||
584 | /* Timeout after 48 character intervals */ | ||
585 | buf[9] |= 0x0030; | ||
586 | |||
587 | /* 9. Configure LSR interrupt enable register */ | ||
588 | buf[10] = (MAX3107_WRITE_BIT | MAX3107_LSR_IRQEN_REG); | ||
589 | /* Enable RX timeout interrupt */ | ||
590 | buf[10] |= MAX3107_LSR_RXTO_BIT; | ||
591 | |||
592 | /* Perform SPI transfer */ | ||
593 | if (max3107_rw(s, (u8 *)buf, NULL, 22)) | ||
594 | dev_err(&s->spi->dev, "SPI transfer for init failed\n"); | ||
595 | |||
596 | /* 10. Clear IRQ status register by reading it */ | ||
597 | buf[0] = MAX3107_IRQSTS_REG; | ||
598 | |||
599 | /* 11. Configure interrupt enable register */ | ||
600 | /* Enable LSR interrupt */ | ||
601 | s->irqen_reg = MAX3107_IRQ_LSR_BIT; | ||
602 | /* Enable RX FIFO interrupt */ | ||
603 | s->irqen_reg |= MAX3107_IRQ_RXFIFO_BIT; | ||
604 | buf[1] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG) | ||
605 | | s->irqen_reg; | ||
606 | |||
607 | /* 12. Clear FIFO reset that was set in step 6 */ | ||
608 | buf[2] = (MAX3107_WRITE_BIT | MAX3107_MODE2_REG); | ||
609 | if (s->loopback) { | ||
610 | /* Keep loopback enabled */ | ||
611 | buf[2] |= MAX3107_MODE2_LOOPBACK_BIT; | ||
612 | } | ||
613 | |||
614 | /* Perform SPI transfer */ | ||
615 | if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 6)) | ||
616 | dev_err(&s->spi->dev, "SPI transfer for init failed\n"); | ||
617 | |||
618 | } | ||
619 | |||
620 | /* IRQ handler */ | ||
621 | static irqreturn_t max3107_irq(int irqno, void *dev_id) | ||
622 | { | ||
623 | struct max3107_port *s = dev_id; | ||
624 | |||
625 | if (irqno != s->spi->irq) { | ||
626 | /* Unexpected IRQ */ | ||
627 | return IRQ_NONE; | ||
628 | } | ||
629 | |||
630 | /* Indicate irq */ | ||
631 | s->handle_irq = 1; | ||
632 | |||
633 | /* Trigger work thread */ | ||
634 | max3107_dowork(s); | ||
635 | |||
636 | return IRQ_HANDLED; | ||
637 | } | ||
638 | |||
639 | /* HW suspension function | ||
640 | * | ||
641 | * Currently autosleep is used to decrease current consumption, alternative | ||
642 | * approach would be to set the chip to reset mode if UART is not being | ||
643 | * used but that would mess the GPIOs | ||
644 | * | ||
645 | */ | ||
646 | void max3107_hw_susp(struct max3107_port *s, int suspend) | ||
647 | { | ||
648 | pr_debug("enter, suspend %d\n", suspend); | ||
649 | |||
650 | if (suspend) { | ||
651 | /* Suspend requested, | ||
652 | * enable autosleep to decrease current consumption | ||
653 | */ | ||
654 | s->suspended = 1; | ||
655 | max3107_set_sleep(s, MAX3107_ENABLE_AUTOSLEEP); | ||
656 | } else { | ||
657 | /* Resume requested, | ||
658 | * disable autosleep | ||
659 | */ | ||
660 | s->suspended = 0; | ||
661 | max3107_set_sleep(s, MAX3107_DISABLE_AUTOSLEEP); | ||
662 | } | ||
663 | } | ||
664 | EXPORT_SYMBOL_GPL(max3107_hw_susp); | ||
665 | |||
666 | /* Modem status IRQ enabling */ | ||
667 | static void max3107_enable_ms(struct uart_port *port) | ||
668 | { | ||
669 | /* Modem status not supported */ | ||
670 | } | ||
671 | |||
672 | /* Data send function */ | ||
673 | static void max3107_start_tx(struct uart_port *port) | ||
674 | { | ||
675 | struct max3107_port *s = container_of(port, struct max3107_port, port); | ||
676 | |||
677 | /* Trigger work thread for sending data */ | ||
678 | max3107_dowork(s); | ||
679 | } | ||
680 | |||
681 | /* Function for checking that there is no pending transfers */ | ||
682 | static unsigned int max3107_tx_empty(struct uart_port *port) | ||
683 | { | ||
684 | struct max3107_port *s = container_of(port, struct max3107_port, port); | ||
685 | |||
686 | pr_debug("returning %d\n", | ||
687 | (s->tx_fifo_empty && uart_circ_empty(&s->port.state->xmit))); | ||
688 | return s->tx_fifo_empty && uart_circ_empty(&s->port.state->xmit); | ||
689 | } | ||
690 | |||
691 | /* Function for stopping RX */ | ||
692 | static void max3107_stop_rx(struct uart_port *port) | ||
693 | { | ||
694 | struct max3107_port *s = container_of(port, struct max3107_port, port); | ||
695 | unsigned long flags; | ||
696 | |||
697 | /* Set RX disabled in MODE 1 register */ | ||
698 | spin_lock_irqsave(&s->data_lock, flags); | ||
699 | s->mode1_reg |= MAX3107_MODE1_RXDIS_BIT; | ||
700 | s->mode1_commit = 1; | ||
701 | spin_unlock_irqrestore(&s->data_lock, flags); | ||
702 | /* Set RX disabled */ | ||
703 | s->rx_enabled = 0; | ||
704 | /* Trigger work thread for doing the actual configuration change */ | ||
705 | max3107_dowork(s); | ||
706 | } | ||
707 | |||
708 | /* Function for returning control pin states */ | ||
709 | static unsigned int max3107_get_mctrl(struct uart_port *port) | ||
710 | { | ||
711 | /* DCD and DSR are not wired and CTS/RTS is handled automatically | ||
712 | * so just indicate DSR and CAR asserted | ||
713 | */ | ||
714 | return TIOCM_DSR | TIOCM_CAR; | ||
715 | } | ||
716 | |||
717 | /* Function for setting control pin states */ | ||
718 | static void max3107_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
719 | { | ||
720 | /* DCD and DSR are not wired and CTS/RTS is hadnled automatically | ||
721 | * so do nothing | ||
722 | */ | ||
723 | } | ||
724 | |||
725 | /* Function for configuring UART parameters */ | ||
726 | static void max3107_set_termios(struct uart_port *port, | ||
727 | struct ktermios *termios, | ||
728 | struct ktermios *old) | ||
729 | { | ||
730 | struct max3107_port *s = container_of(port, struct max3107_port, port); | ||
731 | struct tty_struct *tty; | ||
732 | int baud; | ||
733 | u16 new_lcr = 0; | ||
734 | u32 new_brg = 0; | ||
735 | unsigned long flags; | ||
736 | |||
737 | if (!port->state) | ||
738 | return; | ||
739 | |||
740 | tty = port->state->port.tty; | ||
741 | if (!tty) | ||
742 | return; | ||
743 | |||
744 | /* Get new LCR register values */ | ||
745 | /* Word size */ | ||
746 | if ((termios->c_cflag & CSIZE) == CS7) | ||
747 | new_lcr |= MAX3107_LCR_WORD_LEN_7; | ||
748 | else | ||
749 | new_lcr |= MAX3107_LCR_WORD_LEN_8; | ||
750 | |||
751 | /* Parity */ | ||
752 | if (termios->c_cflag & PARENB) { | ||
753 | new_lcr |= MAX3107_LCR_PARITY_BIT; | ||
754 | if (!(termios->c_cflag & PARODD)) | ||
755 | new_lcr |= MAX3107_LCR_EVENPARITY_BIT; | ||
756 | } | ||
757 | |||
758 | /* Stop bits */ | ||
759 | if (termios->c_cflag & CSTOPB) { | ||
760 | /* 2 stop bits */ | ||
761 | new_lcr |= MAX3107_LCR_STOPLEN_BIT; | ||
762 | } | ||
763 | |||
764 | /* Mask termios capabilities we don't support */ | ||
765 | termios->c_cflag &= ~CMSPAR; | ||
766 | |||
767 | /* Set status ignore mask */ | ||
768 | s->port.ignore_status_mask = 0; | ||
769 | if (termios->c_iflag & IGNPAR) | ||
770 | s->port.ignore_status_mask |= MAX3107_ALL_ERRORS; | ||
771 | |||
772 | /* Set low latency to immediately handle pushed data */ | ||
773 | s->port.state->port.tty->low_latency = 1; | ||
774 | |||
775 | /* Get new baud rate generator configuration */ | ||
776 | baud = tty_get_baud_rate(tty); | ||
777 | |||
778 | spin_lock_irqsave(&s->data_lock, flags); | ||
779 | new_brg = get_new_brg(baud, s); | ||
780 | /* if can't find the corrent config, use previous */ | ||
781 | if (!new_brg) { | ||
782 | baud = s->baud; | ||
783 | new_brg = s->brg_cfg; | ||
784 | } | ||
785 | spin_unlock_irqrestore(&s->data_lock, flags); | ||
786 | tty_termios_encode_baud_rate(termios, baud, baud); | ||
787 | s->baud = baud; | ||
788 | |||
789 | /* Update timeout according to new baud rate */ | ||
790 | uart_update_timeout(port, termios->c_cflag, baud); | ||
791 | |||
792 | spin_lock_irqsave(&s->data_lock, flags); | ||
793 | if (s->lcr_reg != new_lcr) { | ||
794 | s->lcr_reg = new_lcr; | ||
795 | s->lcr_commit = 1; | ||
796 | } | ||
797 | if (s->brg_cfg != new_brg) { | ||
798 | s->brg_cfg = new_brg; | ||
799 | s->brg_commit = 1; | ||
800 | } | ||
801 | spin_unlock_irqrestore(&s->data_lock, flags); | ||
802 | |||
803 | /* Trigger work thread for doing the actual configuration change */ | ||
804 | max3107_dowork(s); | ||
805 | } | ||
806 | |||
807 | /* Port shutdown function */ | ||
808 | static void max3107_shutdown(struct uart_port *port) | ||
809 | { | ||
810 | struct max3107_port *s = container_of(port, struct max3107_port, port); | ||
811 | |||
812 | if (s->suspended && s->pdata->hw_suspend) | ||
813 | s->pdata->hw_suspend(s, 0); | ||
814 | |||
815 | /* Free the interrupt */ | ||
816 | free_irq(s->spi->irq, s); | ||
817 | |||
818 | if (s->workqueue) { | ||
819 | /* Flush and destroy work queue */ | ||
820 | flush_workqueue(s->workqueue); | ||
821 | destroy_workqueue(s->workqueue); | ||
822 | s->workqueue = NULL; | ||
823 | } | ||
824 | |||
825 | /* Suspend HW */ | ||
826 | if (s->pdata->hw_suspend) | ||
827 | s->pdata->hw_suspend(s, 1); | ||
828 | } | ||
829 | |||
830 | /* Port startup function */ | ||
831 | static int max3107_startup(struct uart_port *port) | ||
832 | { | ||
833 | struct max3107_port *s = container_of(port, struct max3107_port, port); | ||
834 | |||
835 | /* Initialize work queue */ | ||
836 | s->workqueue = create_freezeable_workqueue("max3107"); | ||
837 | if (!s->workqueue) { | ||
838 | dev_err(&s->spi->dev, "Workqueue creation failed\n"); | ||
839 | return -EBUSY; | ||
840 | } | ||
841 | INIT_WORK(&s->work, max3107_work); | ||
842 | |||
843 | /* Setup IRQ */ | ||
844 | if (request_irq(s->spi->irq, max3107_irq, IRQF_TRIGGER_FALLING, | ||
845 | "max3107", s)) { | ||
846 | dev_err(&s->spi->dev, "IRQ reguest failed\n"); | ||
847 | destroy_workqueue(s->workqueue); | ||
848 | s->workqueue = NULL; | ||
849 | return -EBUSY; | ||
850 | } | ||
851 | |||
852 | /* Resume HW */ | ||
853 | if (s->pdata->hw_suspend) | ||
854 | s->pdata->hw_suspend(s, 0); | ||
855 | |||
856 | /* Init registers */ | ||
857 | max3107_register_init(s); | ||
858 | |||
859 | return 0; | ||
860 | } | ||
861 | |||
862 | /* Port type function */ | ||
863 | static const char *max3107_type(struct uart_port *port) | ||
864 | { | ||
865 | struct max3107_port *s = container_of(port, struct max3107_port, port); | ||
866 | return s->spi->modalias; | ||
867 | } | ||
868 | |||
869 | /* Port release function */ | ||
870 | static void max3107_release_port(struct uart_port *port) | ||
871 | { | ||
872 | /* Do nothing */ | ||
873 | } | ||
874 | |||
875 | /* Port request function */ | ||
876 | static int max3107_request_port(struct uart_port *port) | ||
877 | { | ||
878 | /* Do nothing */ | ||
879 | return 0; | ||
880 | } | ||
881 | |||
882 | /* Port config function */ | ||
883 | static void max3107_config_port(struct uart_port *port, int flags) | ||
884 | { | ||
885 | struct max3107_port *s = container_of(port, struct max3107_port, port); | ||
886 | s->port.type = PORT_MAX3107; | ||
887 | } | ||
888 | |||
889 | /* Port verify function */ | ||
890 | static int max3107_verify_port(struct uart_port *port, | ||
891 | struct serial_struct *ser) | ||
892 | { | ||
893 | if (ser->type == PORT_UNKNOWN || ser->type == PORT_MAX3107) | ||
894 | return 0; | ||
895 | |||
896 | return -EINVAL; | ||
897 | } | ||
898 | |||
899 | /* Port stop TX function */ | ||
900 | static void max3107_stop_tx(struct uart_port *port) | ||
901 | { | ||
902 | /* Do nothing */ | ||
903 | } | ||
904 | |||
905 | /* Port break control function */ | ||
906 | static void max3107_break_ctl(struct uart_port *port, int break_state) | ||
907 | { | ||
908 | /* We don't support break control, do nothing */ | ||
909 | } | ||
910 | |||
911 | |||
912 | /* Port functions */ | ||
913 | static struct uart_ops max3107_ops = { | ||
914 | .tx_empty = max3107_tx_empty, | ||
915 | .set_mctrl = max3107_set_mctrl, | ||
916 | .get_mctrl = max3107_get_mctrl, | ||
917 | .stop_tx = max3107_stop_tx, | ||
918 | .start_tx = max3107_start_tx, | ||
919 | .stop_rx = max3107_stop_rx, | ||
920 | .enable_ms = max3107_enable_ms, | ||
921 | .break_ctl = max3107_break_ctl, | ||
922 | .startup = max3107_startup, | ||
923 | .shutdown = max3107_shutdown, | ||
924 | .set_termios = max3107_set_termios, | ||
925 | .type = max3107_type, | ||
926 | .release_port = max3107_release_port, | ||
927 | .request_port = max3107_request_port, | ||
928 | .config_port = max3107_config_port, | ||
929 | .verify_port = max3107_verify_port, | ||
930 | }; | ||
931 | |||
932 | /* UART driver data */ | ||
933 | static struct uart_driver max3107_uart_driver = { | ||
934 | .owner = THIS_MODULE, | ||
935 | .driver_name = "ttyMAX", | ||
936 | .dev_name = "ttyMAX", | ||
937 | .nr = 1, | ||
938 | }; | ||
939 | |||
940 | static int driver_registered = 0; | ||
941 | |||
942 | |||
943 | |||
944 | /* 'Generic' platform data */ | ||
945 | static struct max3107_plat generic_plat_data = { | ||
946 | .loopback = 0, | ||
947 | .ext_clk = 1, | ||
948 | .hw_suspend = max3107_hw_susp, | ||
949 | .polled_mode = 0, | ||
950 | .poll_time = 0, | ||
951 | }; | ||
952 | |||
953 | |||
954 | /*******************************************************************/ | ||
955 | |||
956 | /** | ||
957 | * max3107_probe - SPI bus probe entry point | ||
958 | * @spi: the spi device | ||
959 | * | ||
960 | * SPI wants us to probe this device and if appropriate claim it. | ||
961 | * Perform any platform specific requirements and then initialise | ||
962 | * the device. | ||
963 | */ | ||
964 | |||
965 | int max3107_probe(struct spi_device *spi, struct max3107_plat *pdata) | ||
966 | { | ||
967 | struct max3107_port *s; | ||
968 | u16 buf[2]; /* Buffer for SPI transfers */ | ||
969 | int retval; | ||
970 | |||
971 | pr_info("enter max3107 probe\n"); | ||
972 | |||
973 | /* Allocate port structure */ | ||
974 | s = kzalloc(sizeof(*s), GFP_KERNEL); | ||
975 | if (!s) { | ||
976 | pr_err("Allocating port structure failed\n"); | ||
977 | return -ENOMEM; | ||
978 | } | ||
979 | |||
980 | s->pdata = pdata; | ||
981 | |||
982 | /* SPI Rx buffer | ||
983 | * +2 for RX FIFO interrupt | ||
984 | * disabling and RX level query | ||
985 | */ | ||
986 | s->rxbuf = kzalloc(sizeof(u16) * (MAX3107_RX_FIFO_SIZE+2), GFP_KERNEL); | ||
987 | if (!s->rxbuf) { | ||
988 | pr_err("Allocating RX buffer failed\n"); | ||
989 | retval = -ENOMEM; | ||
990 | goto err_free4; | ||
991 | } | ||
992 | s->rxstr = kzalloc(sizeof(u8) * MAX3107_RX_FIFO_SIZE, GFP_KERNEL); | ||
993 | if (!s->rxstr) { | ||
994 | pr_err("Allocating RX buffer failed\n"); | ||
995 | retval = -ENOMEM; | ||
996 | goto err_free3; | ||
997 | } | ||
998 | /* SPI Tx buffer | ||
999 | * SPI transfer buffer | ||
1000 | * +3 for TX FIFO empty | ||
1001 | * interrupt disabling and | ||
1002 | * enabling and TX enabling | ||
1003 | */ | ||
1004 | s->txbuf = kzalloc(sizeof(u16) * MAX3107_TX_FIFO_SIZE + 3, GFP_KERNEL); | ||
1005 | if (!s->txbuf) { | ||
1006 | pr_err("Allocating TX buffer failed\n"); | ||
1007 | retval = -ENOMEM; | ||
1008 | goto err_free2; | ||
1009 | } | ||
1010 | /* Initialize shared data lock */ | ||
1011 | spin_lock_init(&s->data_lock); | ||
1012 | |||
1013 | /* SPI intializations */ | ||
1014 | dev_set_drvdata(&spi->dev, s); | ||
1015 | spi->mode = SPI_MODE_0; | ||
1016 | spi->dev.platform_data = pdata; | ||
1017 | spi->bits_per_word = 16; | ||
1018 | s->ext_clk = pdata->ext_clk; | ||
1019 | s->loopback = pdata->loopback; | ||
1020 | spi_setup(spi); | ||
1021 | s->spi = spi; | ||
1022 | |||
1023 | /* Check REV ID to ensure we are talking to what we expect */ | ||
1024 | buf[0] = MAX3107_REVID_REG; | ||
1025 | if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 2)) { | ||
1026 | dev_err(&s->spi->dev, "SPI transfer for REVID read failed\n"); | ||
1027 | retval = -EIO; | ||
1028 | goto err_free1; | ||
1029 | } | ||
1030 | if ((buf[0] & MAX3107_SPI_RX_DATA_MASK) != MAX3107_REVID1 && | ||
1031 | (buf[0] & MAX3107_SPI_RX_DATA_MASK) != MAX3107_REVID2) { | ||
1032 | dev_err(&s->spi->dev, "REVID %x does not match\n", | ||
1033 | (buf[0] & MAX3107_SPI_RX_DATA_MASK)); | ||
1034 | retval = -ENODEV; | ||
1035 | goto err_free1; | ||
1036 | } | ||
1037 | |||
1038 | /* Disable all interrupts */ | ||
1039 | buf[0] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG | 0x0000); | ||
1040 | buf[0] |= 0x0000; | ||
1041 | |||
1042 | /* Configure clock source */ | ||
1043 | buf[1] = (MAX3107_WRITE_BIT | MAX3107_CLKSRC_REG); | ||
1044 | if (s->ext_clk) { | ||
1045 | /* External clock */ | ||
1046 | buf[1] |= MAX3107_CLKSRC_EXTCLK_BIT; | ||
1047 | } | ||
1048 | |||
1049 | /* PLL bypass ON */ | ||
1050 | buf[1] |= MAX3107_CLKSRC_PLLBYP_BIT; | ||
1051 | |||
1052 | /* Perform SPI transfer */ | ||
1053 | if (max3107_rw(s, (u8 *)buf, NULL, 4)) { | ||
1054 | dev_err(&s->spi->dev, "SPI transfer for init failed\n"); | ||
1055 | retval = -EIO; | ||
1056 | goto err_free1; | ||
1057 | } | ||
1058 | |||
1059 | /* Register UART driver */ | ||
1060 | if (!driver_registered) { | ||
1061 | retval = uart_register_driver(&max3107_uart_driver); | ||
1062 | if (retval) { | ||
1063 | dev_err(&s->spi->dev, "Registering UART driver failed\n"); | ||
1064 | goto err_free1; | ||
1065 | } | ||
1066 | driver_registered = 1; | ||
1067 | } | ||
1068 | |||
1069 | /* Initialize UART port data */ | ||
1070 | s->port.fifosize = 128; | ||
1071 | s->port.ops = &max3107_ops; | ||
1072 | s->port.line = 0; | ||
1073 | s->port.dev = &spi->dev; | ||
1074 | s->port.uartclk = 9600; | ||
1075 | s->port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; | ||
1076 | s->port.irq = s->spi->irq; | ||
1077 | s->port.type = PORT_MAX3107; | ||
1078 | |||
1079 | /* Add UART port */ | ||
1080 | retval = uart_add_one_port(&max3107_uart_driver, &s->port); | ||
1081 | if (retval < 0) { | ||
1082 | dev_err(&s->spi->dev, "Adding UART port failed\n"); | ||
1083 | goto err_free1; | ||
1084 | } | ||
1085 | |||
1086 | if (pdata->configure) { | ||
1087 | retval = pdata->configure(s); | ||
1088 | if (retval < 0) | ||
1089 | goto err_free1; | ||
1090 | } | ||
1091 | |||
1092 | /* Go to suspend mode */ | ||
1093 | if (pdata->hw_suspend) | ||
1094 | pdata->hw_suspend(s, 1); | ||
1095 | |||
1096 | return 0; | ||
1097 | |||
1098 | err_free1: | ||
1099 | kfree(s->txbuf); | ||
1100 | err_free2: | ||
1101 | kfree(s->rxstr); | ||
1102 | err_free3: | ||
1103 | kfree(s->rxbuf); | ||
1104 | err_free4: | ||
1105 | kfree(s); | ||
1106 | return retval; | ||
1107 | } | ||
1108 | EXPORT_SYMBOL_GPL(max3107_probe); | ||
1109 | |||
1110 | /* Driver remove function */ | ||
1111 | int max3107_remove(struct spi_device *spi) | ||
1112 | { | ||
1113 | struct max3107_port *s = dev_get_drvdata(&spi->dev); | ||
1114 | |||
1115 | pr_info("enter max3107 remove\n"); | ||
1116 | |||
1117 | /* Remove port */ | ||
1118 | if (uart_remove_one_port(&max3107_uart_driver, &s->port)) | ||
1119 | dev_warn(&s->spi->dev, "Removing UART port failed\n"); | ||
1120 | |||
1121 | |||
1122 | /* Free TxRx buffer */ | ||
1123 | kfree(s->rxbuf); | ||
1124 | kfree(s->rxstr); | ||
1125 | kfree(s->txbuf); | ||
1126 | |||
1127 | /* Free port structure */ | ||
1128 | kfree(s); | ||
1129 | |||
1130 | return 0; | ||
1131 | } | ||
1132 | EXPORT_SYMBOL_GPL(max3107_remove); | ||
1133 | |||
1134 | /* Driver suspend function */ | ||
1135 | int max3107_suspend(struct spi_device *spi, pm_message_t state) | ||
1136 | { | ||
1137 | #ifdef CONFIG_PM | ||
1138 | struct max3107_port *s = dev_get_drvdata(&spi->dev); | ||
1139 | |||
1140 | pr_debug("enter suspend\n"); | ||
1141 | |||
1142 | /* Suspend UART port */ | ||
1143 | uart_suspend_port(&max3107_uart_driver, &s->port); | ||
1144 | |||
1145 | /* Go to suspend mode */ | ||
1146 | if (s->pdata->hw_suspend) | ||
1147 | s->pdata->hw_suspend(s, 1); | ||
1148 | #endif /* CONFIG_PM */ | ||
1149 | return 0; | ||
1150 | } | ||
1151 | EXPORT_SYMBOL_GPL(max3107_suspend); | ||
1152 | |||
1153 | /* Driver resume function */ | ||
1154 | int max3107_resume(struct spi_device *spi) | ||
1155 | { | ||
1156 | #ifdef CONFIG_PM | ||
1157 | struct max3107_port *s = dev_get_drvdata(&spi->dev); | ||
1158 | |||
1159 | pr_debug("enter resume\n"); | ||
1160 | |||
1161 | /* Resume from suspend */ | ||
1162 | if (s->pdata->hw_suspend) | ||
1163 | s->pdata->hw_suspend(s, 0); | ||
1164 | |||
1165 | /* Resume UART port */ | ||
1166 | uart_resume_port(&max3107_uart_driver, &s->port); | ||
1167 | #endif /* CONFIG_PM */ | ||
1168 | return 0; | ||
1169 | } | ||
1170 | EXPORT_SYMBOL_GPL(max3107_resume); | ||
1171 | |||
1172 | static int max3107_probe_generic(struct spi_device *spi) | ||
1173 | { | ||
1174 | return max3107_probe(spi, &generic_plat_data); | ||
1175 | } | ||
1176 | |||
1177 | /* Spi driver data */ | ||
1178 | static struct spi_driver max3107_driver = { | ||
1179 | .driver = { | ||
1180 | .name = "max3107", | ||
1181 | .bus = &spi_bus_type, | ||
1182 | .owner = THIS_MODULE, | ||
1183 | }, | ||
1184 | .probe = max3107_probe_generic, | ||
1185 | .remove = __devexit_p(max3107_remove), | ||
1186 | .suspend = max3107_suspend, | ||
1187 | .resume = max3107_resume, | ||
1188 | }; | ||
1189 | |||
1190 | /* Driver init function */ | ||
1191 | static int __init max3107_init(void) | ||
1192 | { | ||
1193 | pr_info("enter max3107 init\n"); | ||
1194 | return spi_register_driver(&max3107_driver); | ||
1195 | } | ||
1196 | |||
1197 | /* Driver exit function */ | ||
1198 | static void __exit max3107_exit(void) | ||
1199 | { | ||
1200 | pr_info("enter max3107 exit\n"); | ||
1201 | /* Unregister UART driver */ | ||
1202 | if (driver_registered) | ||
1203 | uart_unregister_driver(&max3107_uart_driver); | ||
1204 | spi_unregister_driver(&max3107_driver); | ||
1205 | } | ||
1206 | |||
1207 | module_init(max3107_init); | ||
1208 | module_exit(max3107_exit); | ||
1209 | |||
1210 | MODULE_DESCRIPTION("MAX3107 driver"); | ||
1211 | MODULE_AUTHOR("Aavamobile"); | ||
1212 | MODULE_ALIAS("max3107-spi"); | ||
1213 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/serial/max3107.h b/drivers/serial/max3107.h new file mode 100644 index 000000000000..7ab632392502 --- /dev/null +++ b/drivers/serial/max3107.h | |||
@@ -0,0 +1,441 @@ | |||
1 | /* | ||
2 | * max3107.h - spi uart protocol driver header for Maxim 3107 | ||
3 | * | ||
4 | * Copyright (C) Aavamobile 2009 | ||
5 | * Based on serial_max3100.h by Christian Pellegrin | ||
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 as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | */ | ||
12 | |||
13 | #ifndef _MAX3107_H | ||
14 | #define _MAX3107_H | ||
15 | |||
16 | /* Serial error status definitions */ | ||
17 | #define MAX3107_PARITY_ERROR 1 | ||
18 | #define MAX3107_FRAME_ERROR 2 | ||
19 | #define MAX3107_OVERRUN_ERROR 4 | ||
20 | #define MAX3107_ALL_ERRORS (MAX3107_PARITY_ERROR | \ | ||
21 | MAX3107_FRAME_ERROR | \ | ||
22 | MAX3107_OVERRUN_ERROR) | ||
23 | |||
24 | /* GPIO definitions */ | ||
25 | #define MAX3107_GPIO_BASE 88 | ||
26 | #define MAX3107_GPIO_COUNT 4 | ||
27 | |||
28 | |||
29 | /* GPIO connected to chip's reset pin */ | ||
30 | #define MAX3107_RESET_GPIO 87 | ||
31 | |||
32 | |||
33 | /* Chip reset delay */ | ||
34 | #define MAX3107_RESET_DELAY 10 | ||
35 | |||
36 | /* Chip wakeup delay */ | ||
37 | #define MAX3107_WAKEUP_DELAY 50 | ||
38 | |||
39 | |||
40 | /* Sleep mode definitions */ | ||
41 | #define MAX3107_DISABLE_FORCED_SLEEP 0 | ||
42 | #define MAX3107_ENABLE_FORCED_SLEEP 1 | ||
43 | #define MAX3107_DISABLE_AUTOSLEEP 2 | ||
44 | #define MAX3107_ENABLE_AUTOSLEEP 3 | ||
45 | |||
46 | |||
47 | /* Definitions for register access with SPI transfers | ||
48 | * | ||
49 | * SPI transfer format: | ||
50 | * | ||
51 | * Master to slave bits xzzzzzzzyyyyyyyy | ||
52 | * Slave to master bits aaaaaaaabbbbbbbb | ||
53 | * | ||
54 | * where: | ||
55 | * x = 0 for reads, 1 for writes | ||
56 | * z = register address | ||
57 | * y = new register value if write, 0 if read | ||
58 | * a = unspecified | ||
59 | * b = register value if read, unspecified if write | ||
60 | */ | ||
61 | |||
62 | /* SPI speed */ | ||
63 | #define MAX3107_SPI_SPEED (3125000 * 2) | ||
64 | |||
65 | /* Write bit */ | ||
66 | #define MAX3107_WRITE_BIT (1 << 15) | ||
67 | |||
68 | /* SPI TX data mask */ | ||
69 | #define MAX3107_SPI_RX_DATA_MASK (0x00ff) | ||
70 | |||
71 | /* SPI RX data mask */ | ||
72 | #define MAX3107_SPI_TX_DATA_MASK (0x00ff) | ||
73 | |||
74 | /* Register access masks */ | ||
75 | #define MAX3107_RHR_REG (0x0000) /* RX FIFO */ | ||
76 | #define MAX3107_THR_REG (0x0000) /* TX FIFO */ | ||
77 | #define MAX3107_IRQEN_REG (0x0100) /* IRQ enable */ | ||
78 | #define MAX3107_IRQSTS_REG (0x0200) /* IRQ status */ | ||
79 | #define MAX3107_LSR_IRQEN_REG (0x0300) /* LSR IRQ enable */ | ||
80 | #define MAX3107_LSR_IRQSTS_REG (0x0400) /* LSR IRQ status */ | ||
81 | #define MAX3107_SPCHR_IRQEN_REG (0x0500) /* Special char IRQ enable */ | ||
82 | #define MAX3107_SPCHR_IRQSTS_REG (0x0600) /* Special char IRQ status */ | ||
83 | #define MAX3107_STS_IRQEN_REG (0x0700) /* Status IRQ enable */ | ||
84 | #define MAX3107_STS_IRQSTS_REG (0x0800) /* Status IRQ status */ | ||
85 | #define MAX3107_MODE1_REG (0x0900) /* MODE1 */ | ||
86 | #define MAX3107_MODE2_REG (0x0a00) /* MODE2 */ | ||
87 | #define MAX3107_LCR_REG (0x0b00) /* LCR */ | ||
88 | #define MAX3107_RXTO_REG (0x0c00) /* RX timeout */ | ||
89 | #define MAX3107_HDPIXDELAY_REG (0x0d00) /* Auto transceiver delays */ | ||
90 | #define MAX3107_IRDA_REG (0x0e00) /* IRDA settings */ | ||
91 | #define MAX3107_FLOWLVL_REG (0x0f00) /* Flow control levels */ | ||
92 | #define MAX3107_FIFOTRIGLVL_REG (0x1000) /* FIFO IRQ trigger levels */ | ||
93 | #define MAX3107_TXFIFOLVL_REG (0x1100) /* TX FIFO level */ | ||
94 | #define MAX3107_RXFIFOLVL_REG (0x1200) /* RX FIFO level */ | ||
95 | #define MAX3107_FLOWCTRL_REG (0x1300) /* Flow control */ | ||
96 | #define MAX3107_XON1_REG (0x1400) /* XON1 character */ | ||
97 | #define MAX3107_XON2_REG (0x1500) /* XON2 character */ | ||
98 | #define MAX3107_XOFF1_REG (0x1600) /* XOFF1 character */ | ||
99 | #define MAX3107_XOFF2_REG (0x1700) /* XOFF2 character */ | ||
100 | #define MAX3107_GPIOCFG_REG (0x1800) /* GPIO config */ | ||
101 | #define MAX3107_GPIODATA_REG (0x1900) /* GPIO data */ | ||
102 | #define MAX3107_PLLCFG_REG (0x1a00) /* PLL config */ | ||
103 | #define MAX3107_BRGCFG_REG (0x1b00) /* Baud rate generator conf */ | ||
104 | #define MAX3107_BRGDIVLSB_REG (0x1c00) /* Baud rate divisor LSB */ | ||
105 | #define MAX3107_BRGDIVMSB_REG (0x1d00) /* Baud rate divisor MSB */ | ||
106 | #define MAX3107_CLKSRC_REG (0x1e00) /* Clock source */ | ||
107 | #define MAX3107_REVID_REG (0x1f00) /* Revision identification */ | ||
108 | |||
109 | /* IRQ register bits */ | ||
110 | #define MAX3107_IRQ_LSR_BIT (1 << 0) /* LSR interrupt */ | ||
111 | #define MAX3107_IRQ_SPCHR_BIT (1 << 1) /* Special char interrupt */ | ||
112 | #define MAX3107_IRQ_STS_BIT (1 << 2) /* Status interrupt */ | ||
113 | #define MAX3107_IRQ_RXFIFO_BIT (1 << 3) /* RX FIFO interrupt */ | ||
114 | #define MAX3107_IRQ_TXFIFO_BIT (1 << 4) /* TX FIFO interrupt */ | ||
115 | #define MAX3107_IRQ_TXEMPTY_BIT (1 << 5) /* TX FIFO empty interrupt */ | ||
116 | #define MAX3107_IRQ_RXEMPTY_BIT (1 << 6) /* RX FIFO empty interrupt */ | ||
117 | #define MAX3107_IRQ_CTS_BIT (1 << 7) /* CTS interrupt */ | ||
118 | |||
119 | /* LSR register bits */ | ||
120 | #define MAX3107_LSR_RXTO_BIT (1 << 0) /* RX timeout */ | ||
121 | #define MAX3107_LSR_RXOVR_BIT (1 << 1) /* RX overrun */ | ||
122 | #define MAX3107_LSR_RXPAR_BIT (1 << 2) /* RX parity error */ | ||
123 | #define MAX3107_LSR_FRERR_BIT (1 << 3) /* Frame error */ | ||
124 | #define MAX3107_LSR_RXBRK_BIT (1 << 4) /* RX break */ | ||
125 | #define MAX3107_LSR_RXNOISE_BIT (1 << 5) /* RX noise */ | ||
126 | #define MAX3107_LSR_UNDEF6_BIT (1 << 6) /* Undefined/not used */ | ||
127 | #define MAX3107_LSR_CTS_BIT (1 << 7) /* CTS pin state */ | ||
128 | |||
129 | /* Special character register bits */ | ||
130 | #define MAX3107_SPCHR_XON1_BIT (1 << 0) /* XON1 character */ | ||
131 | #define MAX3107_SPCHR_XON2_BIT (1 << 1) /* XON2 character */ | ||
132 | #define MAX3107_SPCHR_XOFF1_BIT (1 << 2) /* XOFF1 character */ | ||
133 | #define MAX3107_SPCHR_XOFF2_BIT (1 << 3) /* XOFF2 character */ | ||
134 | #define MAX3107_SPCHR_BREAK_BIT (1 << 4) /* RX break */ | ||
135 | #define MAX3107_SPCHR_MULTIDROP_BIT (1 << 5) /* 9-bit multidrop addr char */ | ||
136 | #define MAX3107_SPCHR_UNDEF6_BIT (1 << 6) /* Undefined/not used */ | ||
137 | #define MAX3107_SPCHR_UNDEF7_BIT (1 << 7) /* Undefined/not used */ | ||
138 | |||
139 | /* Status register bits */ | ||
140 | #define MAX3107_STS_GPIO0_BIT (1 << 0) /* GPIO 0 interrupt */ | ||
141 | #define MAX3107_STS_GPIO1_BIT (1 << 1) /* GPIO 1 interrupt */ | ||
142 | #define MAX3107_STS_GPIO2_BIT (1 << 2) /* GPIO 2 interrupt */ | ||
143 | #define MAX3107_STS_GPIO3_BIT (1 << 3) /* GPIO 3 interrupt */ | ||
144 | #define MAX3107_STS_UNDEF4_BIT (1 << 4) /* Undefined/not used */ | ||
145 | #define MAX3107_STS_CLKREADY_BIT (1 << 5) /* Clock ready */ | ||
146 | #define MAX3107_STS_SLEEP_BIT (1 << 6) /* Sleep interrupt */ | ||
147 | #define MAX3107_STS_UNDEF7_BIT (1 << 7) /* Undefined/not used */ | ||
148 | |||
149 | /* MODE1 register bits */ | ||
150 | #define MAX3107_MODE1_RXDIS_BIT (1 << 0) /* RX disable */ | ||
151 | #define MAX3107_MODE1_TXDIS_BIT (1 << 1) /* TX disable */ | ||
152 | #define MAX3107_MODE1_TXHIZ_BIT (1 << 2) /* TX pin three-state */ | ||
153 | #define MAX3107_MODE1_RTSHIZ_BIT (1 << 3) /* RTS pin three-state */ | ||
154 | #define MAX3107_MODE1_TRNSCVCTRL_BIT (1 << 4) /* Transceiver ctrl enable */ | ||
155 | #define MAX3107_MODE1_FORCESLEEP_BIT (1 << 5) /* Force sleep mode */ | ||
156 | #define MAX3107_MODE1_AUTOSLEEP_BIT (1 << 6) /* Auto sleep enable */ | ||
157 | #define MAX3107_MODE1_IRQSEL_BIT (1 << 7) /* IRQ pin enable */ | ||
158 | |||
159 | /* MODE2 register bits */ | ||
160 | #define MAX3107_MODE2_RST_BIT (1 << 0) /* Chip reset */ | ||
161 | #define MAX3107_MODE2_FIFORST_BIT (1 << 1) /* FIFO reset */ | ||
162 | #define MAX3107_MODE2_RXTRIGINV_BIT (1 << 2) /* RX FIFO INT invert */ | ||
163 | #define MAX3107_MODE2_RXEMPTINV_BIT (1 << 3) /* RX FIFO empty INT invert */ | ||
164 | #define MAX3107_MODE2_SPCHR_BIT (1 << 4) /* Special chr detect enable */ | ||
165 | #define MAX3107_MODE2_LOOPBACK_BIT (1 << 5) /* Internal loopback enable */ | ||
166 | #define MAX3107_MODE2_MULTIDROP_BIT (1 << 6) /* 9-bit multidrop enable */ | ||
167 | #define MAX3107_MODE2_ECHOSUPR_BIT (1 << 7) /* ECHO suppression enable */ | ||
168 | |||
169 | /* LCR register bits */ | ||
170 | #define MAX3107_LCR_LENGTH0_BIT (1 << 0) /* Word length bit 0 */ | ||
171 | #define MAX3107_LCR_LENGTH1_BIT (1 << 1) /* Word length bit 1 | ||
172 | * | ||
173 | * Word length bits table: | ||
174 | * 00 -> 5 bit words | ||
175 | * 01 -> 6 bit words | ||
176 | * 10 -> 7 bit words | ||
177 | * 11 -> 8 bit words | ||
178 | */ | ||
179 | #define MAX3107_LCR_STOPLEN_BIT (1 << 2) /* STOP length bit | ||
180 | * | ||
181 | * STOP length bit table: | ||
182 | * 0 -> 1 stop bit | ||
183 | * 1 -> 1-1.5 stop bits if | ||
184 | * word length is 5, | ||
185 | * 2 stop bits otherwise | ||
186 | */ | ||
187 | #define MAX3107_LCR_PARITY_BIT (1 << 3) /* Parity bit enable */ | ||
188 | #define MAX3107_LCR_EVENPARITY_BIT (1 << 4) /* Even parity bit enable */ | ||
189 | #define MAX3107_LCR_FORCEPARITY_BIT (1 << 5) /* 9-bit multidrop parity */ | ||
190 | #define MAX3107_LCR_TXBREAK_BIT (1 << 6) /* TX break enable */ | ||
191 | #define MAX3107_LCR_RTS_BIT (1 << 7) /* RTS pin control */ | ||
192 | #define MAX3107_LCR_WORD_LEN_5 (0x0000) | ||
193 | #define MAX3107_LCR_WORD_LEN_6 (0x0001) | ||
194 | #define MAX3107_LCR_WORD_LEN_7 (0x0002) | ||
195 | #define MAX3107_LCR_WORD_LEN_8 (0x0003) | ||
196 | |||
197 | |||
198 | /* IRDA register bits */ | ||
199 | #define MAX3107_IRDA_IRDAEN_BIT (1 << 0) /* IRDA mode enable */ | ||
200 | #define MAX3107_IRDA_SIR_BIT (1 << 1) /* SIR mode enable */ | ||
201 | #define MAX3107_IRDA_SHORTIR_BIT (1 << 2) /* Short SIR mode enable */ | ||
202 | #define MAX3107_IRDA_MIR_BIT (1 << 3) /* MIR mode enable */ | ||
203 | #define MAX3107_IRDA_RXINV_BIT (1 << 4) /* RX logic inversion enable */ | ||
204 | #define MAX3107_IRDA_TXINV_BIT (1 << 5) /* TX logic inversion enable */ | ||
205 | #define MAX3107_IRDA_UNDEF6_BIT (1 << 6) /* Undefined/not used */ | ||
206 | #define MAX3107_IRDA_UNDEF7_BIT (1 << 7) /* Undefined/not used */ | ||
207 | |||
208 | /* Flow control trigger level register masks */ | ||
209 | #define MAX3107_FLOWLVL_HALT_MASK (0x000f) /* Flow control halt level */ | ||
210 | #define MAX3107_FLOWLVL_RES_MASK (0x00f0) /* Flow control resume level */ | ||
211 | #define MAX3107_FLOWLVL_HALT(words) ((words/8) & 0x000f) | ||
212 | #define MAX3107_FLOWLVL_RES(words) (((words/8) & 0x000f) << 4) | ||
213 | |||
214 | /* FIFO interrupt trigger level register masks */ | ||
215 | #define MAX3107_FIFOTRIGLVL_TX_MASK (0x000f) /* TX FIFO trigger level */ | ||
216 | #define MAX3107_FIFOTRIGLVL_RX_MASK (0x00f0) /* RX FIFO trigger level */ | ||
217 | #define MAX3107_FIFOTRIGLVL_TX(words) ((words/8) & 0x000f) | ||
218 | #define MAX3107_FIFOTRIGLVL_RX(words) (((words/8) & 0x000f) << 4) | ||
219 | |||
220 | /* Flow control register bits */ | ||
221 | #define MAX3107_FLOWCTRL_AUTORTS_BIT (1 << 0) /* Auto RTS flow ctrl enable */ | ||
222 | #define MAX3107_FLOWCTRL_AUTOCTS_BIT (1 << 1) /* Auto CTS flow ctrl enable */ | ||
223 | #define MAX3107_FLOWCTRL_GPIADDR_BIT (1 << 2) /* Enables that GPIO inputs | ||
224 | * are used in conjunction with | ||
225 | * XOFF2 for definition of | ||
226 | * special character */ | ||
227 | #define MAX3107_FLOWCTRL_SWFLOWEN_BIT (1 << 3) /* Auto SW flow ctrl enable */ | ||
228 | #define MAX3107_FLOWCTRL_SWFLOW0_BIT (1 << 4) /* SWFLOW bit 0 */ | ||
229 | #define MAX3107_FLOWCTRL_SWFLOW1_BIT (1 << 5) /* SWFLOW bit 1 | ||
230 | * | ||
231 | * SWFLOW bits 1 & 0 table: | ||
232 | * 00 -> no transmitter flow | ||
233 | * control | ||
234 | * 01 -> receiver compares | ||
235 | * XON2 and XOFF2 | ||
236 | * and controls | ||
237 | * transmitter | ||
238 | * 10 -> receiver compares | ||
239 | * XON1 and XOFF1 | ||
240 | * and controls | ||
241 | * transmitter | ||
242 | * 11 -> receiver compares | ||
243 | * XON1, XON2, XOFF1 and | ||
244 | * XOFF2 and controls | ||
245 | * transmitter | ||
246 | */ | ||
247 | #define MAX3107_FLOWCTRL_SWFLOW2_BIT (1 << 6) /* SWFLOW bit 2 */ | ||
248 | #define MAX3107_FLOWCTRL_SWFLOW3_BIT (1 << 7) /* SWFLOW bit 3 | ||
249 | * | ||
250 | * SWFLOW bits 3 & 2 table: | ||
251 | * 00 -> no received flow | ||
252 | * control | ||
253 | * 01 -> transmitter generates | ||
254 | * XON2 and XOFF2 | ||
255 | * 10 -> transmitter generates | ||
256 | * XON1 and XOFF1 | ||
257 | * 11 -> transmitter generates | ||
258 | * XON1, XON2, XOFF1 and | ||
259 | * XOFF2 | ||
260 | */ | ||
261 | |||
262 | /* GPIO configuration register bits */ | ||
263 | #define MAX3107_GPIOCFG_GP0OUT_BIT (1 << 0) /* GPIO 0 output enable */ | ||
264 | #define MAX3107_GPIOCFG_GP1OUT_BIT (1 << 1) /* GPIO 1 output enable */ | ||
265 | #define MAX3107_GPIOCFG_GP2OUT_BIT (1 << 2) /* GPIO 2 output enable */ | ||
266 | #define MAX3107_GPIOCFG_GP3OUT_BIT (1 << 3) /* GPIO 3 output enable */ | ||
267 | #define MAX3107_GPIOCFG_GP0OD_BIT (1 << 4) /* GPIO 0 open-drain enable */ | ||
268 | #define MAX3107_GPIOCFG_GP1OD_BIT (1 << 5) /* GPIO 1 open-drain enable */ | ||
269 | #define MAX3107_GPIOCFG_GP2OD_BIT (1 << 6) /* GPIO 2 open-drain enable */ | ||
270 | #define MAX3107_GPIOCFG_GP3OD_BIT (1 << 7) /* GPIO 3 open-drain enable */ | ||
271 | |||
272 | /* GPIO DATA register bits */ | ||
273 | #define MAX3107_GPIODATA_GP0OUT_BIT (1 << 0) /* GPIO 0 output value */ | ||
274 | #define MAX3107_GPIODATA_GP1OUT_BIT (1 << 1) /* GPIO 1 output value */ | ||
275 | #define MAX3107_GPIODATA_GP2OUT_BIT (1 << 2) /* GPIO 2 output value */ | ||
276 | #define MAX3107_GPIODATA_GP3OUT_BIT (1 << 3) /* GPIO 3 output value */ | ||
277 | #define MAX3107_GPIODATA_GP0IN_BIT (1 << 4) /* GPIO 0 input value */ | ||
278 | #define MAX3107_GPIODATA_GP1IN_BIT (1 << 5) /* GPIO 1 input value */ | ||
279 | #define MAX3107_GPIODATA_GP2IN_BIT (1 << 6) /* GPIO 2 input value */ | ||
280 | #define MAX3107_GPIODATA_GP3IN_BIT (1 << 7) /* GPIO 3 input value */ | ||
281 | |||
282 | /* PLL configuration register masks */ | ||
283 | #define MAX3107_PLLCFG_PREDIV_MASK (0x003f) /* PLL predivision value */ | ||
284 | #define MAX3107_PLLCFG_PLLFACTOR_MASK (0x00c0) /* PLL multiplication factor */ | ||
285 | |||
286 | /* Baud rate generator configuration register masks and bits */ | ||
287 | #define MAX3107_BRGCFG_FRACT_MASK (0x000f) /* Fractional portion of | ||
288 | * Baud rate generator divisor | ||
289 | */ | ||
290 | #define MAX3107_BRGCFG_2XMODE_BIT (1 << 4) /* Double baud rate */ | ||
291 | #define MAX3107_BRGCFG_4XMODE_BIT (1 << 5) /* Quadruple baud rate */ | ||
292 | #define MAX3107_BRGCFG_UNDEF6_BIT (1 << 6) /* Undefined/not used */ | ||
293 | #define MAX3107_BRGCFG_UNDEF7_BIT (1 << 7) /* Undefined/not used */ | ||
294 | |||
295 | /* Clock source register bits */ | ||
296 | #define MAX3107_CLKSRC_INTOSC_BIT (1 << 0) /* Internal osc enable */ | ||
297 | #define MAX3107_CLKSRC_CRYST_BIT (1 << 1) /* Crystal osc enable */ | ||
298 | #define MAX3107_CLKSRC_PLL_BIT (1 << 2) /* PLL enable */ | ||
299 | #define MAX3107_CLKSRC_PLLBYP_BIT (1 << 3) /* PLL bypass */ | ||
300 | #define MAX3107_CLKSRC_EXTCLK_BIT (1 << 4) /* External clock enable */ | ||
301 | #define MAX3107_CLKSRC_UNDEF5_BIT (1 << 5) /* Undefined/not used */ | ||
302 | #define MAX3107_CLKSRC_UNDEF6_BIT (1 << 6) /* Undefined/not used */ | ||
303 | #define MAX3107_CLKSRC_CLK2RTS_BIT (1 << 7) /* Baud clk to RTS pin */ | ||
304 | |||
305 | |||
306 | /* HW definitions */ | ||
307 | #define MAX3107_RX_FIFO_SIZE 128 | ||
308 | #define MAX3107_TX_FIFO_SIZE 128 | ||
309 | #define MAX3107_REVID1 0x00a0 | ||
310 | #define MAX3107_REVID2 0x00a1 | ||
311 | |||
312 | |||
313 | /* Baud rate generator configuration values for external clock 13MHz */ | ||
314 | #define MAX3107_BRG13_B300 (0x0A9400 | 0x05) | ||
315 | #define MAX3107_BRG13_B600 (0x054A00 | 0x03) | ||
316 | #define MAX3107_BRG13_B1200 (0x02A500 | 0x01) | ||
317 | #define MAX3107_BRG13_B2400 (0x015200 | 0x09) | ||
318 | #define MAX3107_BRG13_B4800 (0x00A900 | 0x04) | ||
319 | #define MAX3107_BRG13_B9600 (0x005400 | 0x0A) | ||
320 | #define MAX3107_BRG13_B19200 (0x002A00 | 0x05) | ||
321 | #define MAX3107_BRG13_B38400 (0x001500 | 0x03) | ||
322 | #define MAX3107_BRG13_B57600 (0x000E00 | 0x02) | ||
323 | #define MAX3107_BRG13_B115200 (0x000700 | 0x01) | ||
324 | #define MAX3107_BRG13_B230400 (0x000300 | 0x08) | ||
325 | #define MAX3107_BRG13_B460800 (0x000100 | 0x0c) | ||
326 | #define MAX3107_BRG13_B921600 (0x000100 | 0x1c) | ||
327 | |||
328 | /* Baud rate generator configuration values for external clock 26MHz */ | ||
329 | #define MAX3107_BRG26_B300 (0x152800 | 0x0A) | ||
330 | #define MAX3107_BRG26_B600 (0x0A9400 | 0x05) | ||
331 | #define MAX3107_BRG26_B1200 (0x054A00 | 0x03) | ||
332 | #define MAX3107_BRG26_B2400 (0x02A500 | 0x01) | ||
333 | #define MAX3107_BRG26_B4800 (0x015200 | 0x09) | ||
334 | #define MAX3107_BRG26_B9600 (0x00A900 | 0x04) | ||
335 | #define MAX3107_BRG26_B19200 (0x005400 | 0x0A) | ||
336 | #define MAX3107_BRG26_B38400 (0x002A00 | 0x05) | ||
337 | #define MAX3107_BRG26_B57600 (0x001C00 | 0x03) | ||
338 | #define MAX3107_BRG26_B115200 (0x000E00 | 0x02) | ||
339 | #define MAX3107_BRG26_B230400 (0x000700 | 0x01) | ||
340 | #define MAX3107_BRG26_B460800 (0x000300 | 0x08) | ||
341 | #define MAX3107_BRG26_B921600 (0x000100 | 0x0C) | ||
342 | |||
343 | /* Baud rate generator configuration values for internal clock */ | ||
344 | #define MAX3107_BRG13_IB300 (0x008000 | 0x00) | ||
345 | #define MAX3107_BRG13_IB600 (0x004000 | 0x00) | ||
346 | #define MAX3107_BRG13_IB1200 (0x002000 | 0x00) | ||
347 | #define MAX3107_BRG13_IB2400 (0x001000 | 0x00) | ||
348 | #define MAX3107_BRG13_IB4800 (0x000800 | 0x00) | ||
349 | #define MAX3107_BRG13_IB9600 (0x000400 | 0x00) | ||
350 | #define MAX3107_BRG13_IB19200 (0x000200 | 0x00) | ||
351 | #define MAX3107_BRG13_IB38400 (0x000100 | 0x00) | ||
352 | #define MAX3107_BRG13_IB57600 (0x000000 | 0x0B) | ||
353 | #define MAX3107_BRG13_IB115200 (0x000000 | 0x05) | ||
354 | #define MAX3107_BRG13_IB230400 (0x000000 | 0x03) | ||
355 | #define MAX3107_BRG13_IB460800 (0x000000 | 0x00) | ||
356 | #define MAX3107_BRG13_IB921600 (0x000000 | 0x00) | ||
357 | |||
358 | |||
359 | struct baud_table { | ||
360 | int baud; | ||
361 | u32 new_brg; | ||
362 | }; | ||
363 | |||
364 | struct max3107_port { | ||
365 | /* UART port structure */ | ||
366 | struct uart_port port; | ||
367 | |||
368 | /* SPI device structure */ | ||
369 | struct spi_device *spi; | ||
370 | |||
371 | #if defined(CONFIG_GPIOLIB) | ||
372 | /* GPIO chip stucture */ | ||
373 | struct gpio_chip chip; | ||
374 | #endif | ||
375 | |||
376 | /* Workqueue that does all the magic */ | ||
377 | struct workqueue_struct *workqueue; | ||
378 | struct work_struct work; | ||
379 | |||
380 | /* Lock for shared data */ | ||
381 | spinlock_t data_lock; | ||
382 | |||
383 | /* Device configuration */ | ||
384 | int ext_clk; /* 1 if external clock used */ | ||
385 | int loopback; /* Current loopback mode state */ | ||
386 | int baud; /* Current baud rate */ | ||
387 | |||
388 | /* State flags */ | ||
389 | int suspended; /* Indicates suspend mode */ | ||
390 | int tx_fifo_empty; /* Flag for TX FIFO state */ | ||
391 | int rx_enabled; /* Flag for receiver state */ | ||
392 | int tx_enabled; /* Flag for transmitter state */ | ||
393 | |||
394 | u16 irqen_reg; /* Current IRQ enable register value */ | ||
395 | /* Shared data */ | ||
396 | u16 mode1_reg; /* Current mode1 register value*/ | ||
397 | int mode1_commit; /* Flag for setting new mode1 register value */ | ||
398 | u16 lcr_reg; /* Current LCR register value */ | ||
399 | int lcr_commit; /* Flag for setting new LCR register value */ | ||
400 | u32 brg_cfg; /* Current Baud rate generator config */ | ||
401 | int brg_commit; /* Flag for setting new baud rate generator | ||
402 | * config | ||
403 | */ | ||
404 | struct baud_table *baud_tbl; | ||
405 | int handle_irq; /* Indicates that IRQ should be handled */ | ||
406 | |||
407 | /* Rx buffer and str*/ | ||
408 | u16 *rxbuf; | ||
409 | u8 *rxstr; | ||
410 | /* Tx buffer*/ | ||
411 | u16 *txbuf; | ||
412 | |||
413 | struct max3107_plat *pdata; /* Platform data */ | ||
414 | }; | ||
415 | |||
416 | /* Platform data structure */ | ||
417 | struct max3107_plat { | ||
418 | /* Loopback mode enable */ | ||
419 | int loopback; | ||
420 | /* External clock enable */ | ||
421 | int ext_clk; | ||
422 | /* Called during the register initialisation */ | ||
423 | void (*init)(struct max3107_port *s); | ||
424 | /* Called when the port is found and configured */ | ||
425 | int (*configure)(struct max3107_port *s); | ||
426 | /* HW suspend function */ | ||
427 | void (*hw_suspend) (struct max3107_port *s, int suspend); | ||
428 | /* Polling mode enable */ | ||
429 | int polled_mode; | ||
430 | /* Polling period if polling mode enabled */ | ||
431 | int poll_time; | ||
432 | }; | ||
433 | |||
434 | extern int max3107_rw(struct max3107_port *s, u8 *tx, u8 *rx, int len); | ||
435 | extern void max3107_hw_susp(struct max3107_port *s, int suspend); | ||
436 | extern int max3107_probe(struct spi_device *spi, struct max3107_plat *pdata); | ||
437 | extern int max3107_remove(struct spi_device *spi); | ||
438 | extern int max3107_suspend(struct spi_device *spi, pm_message_t state); | ||
439 | extern int max3107_resume(struct spi_device *spi); | ||
440 | |||
441 | #endif /* _LINUX_SERIAL_MAX3107_H */ | ||
diff --git a/drivers/serial/mcf.c b/drivers/serial/mcf.c index 0eefb07bebaf..3394b7cc1722 100644 --- a/drivers/serial/mcf.c +++ b/drivers/serial/mcf.c | |||
@@ -70,16 +70,14 @@ static unsigned int mcf_tx_empty(struct uart_port *port) | |||
70 | static unsigned int mcf_get_mctrl(struct uart_port *port) | 70 | static unsigned int mcf_get_mctrl(struct uart_port *port) |
71 | { | 71 | { |
72 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); | 72 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); |
73 | unsigned long flags; | ||
74 | unsigned int sigs; | 73 | unsigned int sigs; |
75 | 74 | ||
76 | spin_lock_irqsave(&port->lock, flags); | ||
77 | sigs = (readb(port->membase + MCFUART_UIPR) & MCFUART_UIPR_CTS) ? | 75 | sigs = (readb(port->membase + MCFUART_UIPR) & MCFUART_UIPR_CTS) ? |
78 | 0 : TIOCM_CTS; | 76 | 0 : TIOCM_CTS; |
79 | sigs |= (pp->sigs & TIOCM_RTS); | 77 | sigs |= (pp->sigs & TIOCM_RTS); |
80 | sigs |= (mcf_getppdcd(port->line) ? TIOCM_CD : 0); | 78 | sigs |= (mcf_getppdcd(port->line) ? TIOCM_CD : 0); |
81 | sigs |= (mcf_getppdtr(port->line) ? TIOCM_DTR : 0); | 79 | sigs |= (mcf_getppdtr(port->line) ? TIOCM_DTR : 0); |
82 | spin_unlock_irqrestore(&port->lock, flags); | 80 | |
83 | return sigs; | 81 | return sigs; |
84 | } | 82 | } |
85 | 83 | ||
@@ -88,16 +86,13 @@ static unsigned int mcf_get_mctrl(struct uart_port *port) | |||
88 | static void mcf_set_mctrl(struct uart_port *port, unsigned int sigs) | 86 | static void mcf_set_mctrl(struct uart_port *port, unsigned int sigs) |
89 | { | 87 | { |
90 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); | 88 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); |
91 | unsigned long flags; | ||
92 | 89 | ||
93 | spin_lock_irqsave(&port->lock, flags); | ||
94 | pp->sigs = sigs; | 90 | pp->sigs = sigs; |
95 | mcf_setppdtr(port->line, (sigs & TIOCM_DTR)); | 91 | mcf_setppdtr(port->line, (sigs & TIOCM_DTR)); |
96 | if (sigs & TIOCM_RTS) | 92 | if (sigs & TIOCM_RTS) |
97 | writeb(MCFUART_UOP_RTS, port->membase + MCFUART_UOP1); | 93 | writeb(MCFUART_UOP_RTS, port->membase + MCFUART_UOP1); |
98 | else | 94 | else |
99 | writeb(MCFUART_UOP_RTS, port->membase + MCFUART_UOP0); | 95 | writeb(MCFUART_UOP_RTS, port->membase + MCFUART_UOP0); |
100 | spin_unlock_irqrestore(&port->lock, flags); | ||
101 | } | 96 | } |
102 | 97 | ||
103 | /****************************************************************************/ | 98 | /****************************************************************************/ |
@@ -105,12 +100,9 @@ static void mcf_set_mctrl(struct uart_port *port, unsigned int sigs) | |||
105 | static void mcf_start_tx(struct uart_port *port) | 100 | static void mcf_start_tx(struct uart_port *port) |
106 | { | 101 | { |
107 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); | 102 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); |
108 | unsigned long flags; | ||
109 | 103 | ||
110 | spin_lock_irqsave(&port->lock, flags); | ||
111 | pp->imr |= MCFUART_UIR_TXREADY; | 104 | pp->imr |= MCFUART_UIR_TXREADY; |
112 | writeb(pp->imr, port->membase + MCFUART_UIMR); | 105 | writeb(pp->imr, port->membase + MCFUART_UIMR); |
113 | spin_unlock_irqrestore(&port->lock, flags); | ||
114 | } | 106 | } |
115 | 107 | ||
116 | /****************************************************************************/ | 108 | /****************************************************************************/ |
@@ -118,12 +110,9 @@ static void mcf_start_tx(struct uart_port *port) | |||
118 | static void mcf_stop_tx(struct uart_port *port) | 110 | static void mcf_stop_tx(struct uart_port *port) |
119 | { | 111 | { |
120 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); | 112 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); |
121 | unsigned long flags; | ||
122 | 113 | ||
123 | spin_lock_irqsave(&port->lock, flags); | ||
124 | pp->imr &= ~MCFUART_UIR_TXREADY; | 114 | pp->imr &= ~MCFUART_UIR_TXREADY; |
125 | writeb(pp->imr, port->membase + MCFUART_UIMR); | 115 | writeb(pp->imr, port->membase + MCFUART_UIMR); |
126 | spin_unlock_irqrestore(&port->lock, flags); | ||
127 | } | 116 | } |
128 | 117 | ||
129 | /****************************************************************************/ | 118 | /****************************************************************************/ |
@@ -131,12 +120,9 @@ static void mcf_stop_tx(struct uart_port *port) | |||
131 | static void mcf_stop_rx(struct uart_port *port) | 120 | static void mcf_stop_rx(struct uart_port *port) |
132 | { | 121 | { |
133 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); | 122 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); |
134 | unsigned long flags; | ||
135 | 123 | ||
136 | spin_lock_irqsave(&port->lock, flags); | ||
137 | pp->imr &= ~MCFUART_UIR_RXREADY; | 124 | pp->imr &= ~MCFUART_UIR_RXREADY; |
138 | writeb(pp->imr, port->membase + MCFUART_UIMR); | 125 | writeb(pp->imr, port->membase + MCFUART_UIMR); |
139 | spin_unlock_irqrestore(&port->lock, flags); | ||
140 | } | 126 | } |
141 | 127 | ||
142 | /****************************************************************************/ | 128 | /****************************************************************************/ |
@@ -263,6 +249,7 @@ static void mcf_set_termios(struct uart_port *port, struct ktermios *termios, | |||
263 | } | 249 | } |
264 | 250 | ||
265 | spin_lock_irqsave(&port->lock, flags); | 251 | spin_lock_irqsave(&port->lock, flags); |
252 | uart_update_timeout(port, termios->c_cflag, baud); | ||
266 | writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR); | 253 | writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR); |
267 | writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR); | 254 | writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR); |
268 | writeb(MCFUART_UCR_CMDRESETMRPTR, port->membase + MCFUART_UCR); | 255 | writeb(MCFUART_UCR_CMDRESETMRPTR, port->membase + MCFUART_UCR); |
@@ -323,7 +310,7 @@ static void mcf_rx_chars(struct mcf_uart *pp) | |||
323 | uart_insert_char(port, status, MCFUART_USR_RXOVERRUN, ch, flag); | 310 | uart_insert_char(port, status, MCFUART_USR_RXOVERRUN, ch, flag); |
324 | } | 311 | } |
325 | 312 | ||
326 | tty_flip_buffer_push(port->info->port.tty); | 313 | tty_flip_buffer_push(port->state->port.tty); |
327 | } | 314 | } |
328 | 315 | ||
329 | /****************************************************************************/ | 316 | /****************************************************************************/ |
@@ -331,7 +318,7 @@ static void mcf_rx_chars(struct mcf_uart *pp) | |||
331 | static void mcf_tx_chars(struct mcf_uart *pp) | 318 | static void mcf_tx_chars(struct mcf_uart *pp) |
332 | { | 319 | { |
333 | struct uart_port *port = &pp->port; | 320 | struct uart_port *port = &pp->port; |
334 | struct circ_buf *xmit = &port->info->xmit; | 321 | struct circ_buf *xmit = &port->state->xmit; |
335 | 322 | ||
336 | if (port->x_char) { | 323 | if (port->x_char) { |
337 | /* Send special char - probably flow control */ | 324 | /* Send special char - probably flow control */ |
@@ -365,13 +352,22 @@ static irqreturn_t mcf_interrupt(int irq, void *data) | |||
365 | struct uart_port *port = data; | 352 | struct uart_port *port = data; |
366 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); | 353 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); |
367 | unsigned int isr; | 354 | unsigned int isr; |
355 | irqreturn_t ret = IRQ_NONE; | ||
368 | 356 | ||
369 | isr = readb(port->membase + MCFUART_UISR) & pp->imr; | 357 | isr = readb(port->membase + MCFUART_UISR) & pp->imr; |
370 | if (isr & MCFUART_UIR_RXREADY) | 358 | |
359 | spin_lock(&port->lock); | ||
360 | if (isr & MCFUART_UIR_RXREADY) { | ||
371 | mcf_rx_chars(pp); | 361 | mcf_rx_chars(pp); |
372 | if (isr & MCFUART_UIR_TXREADY) | 362 | ret = IRQ_HANDLED; |
363 | } | ||
364 | if (isr & MCFUART_UIR_TXREADY) { | ||
373 | mcf_tx_chars(pp); | 365 | mcf_tx_chars(pp); |
374 | return IRQ_HANDLED; | 366 | ret = IRQ_HANDLED; |
367 | } | ||
368 | spin_unlock(&port->lock); | ||
369 | |||
370 | return ret; | ||
375 | } | 371 | } |
376 | 372 | ||
377 | /****************************************************************************/ | 373 | /****************************************************************************/ |
@@ -379,6 +375,7 @@ static irqreturn_t mcf_interrupt(int irq, void *data) | |||
379 | static void mcf_config_port(struct uart_port *port, int flags) | 375 | static void mcf_config_port(struct uart_port *port, int flags) |
380 | { | 376 | { |
381 | port->type = PORT_MCF; | 377 | port->type = PORT_MCF; |
378 | port->fifosize = MCFUART_TXFIFOSIZE; | ||
382 | 379 | ||
383 | /* Clear mask, so no surprise interrupts. */ | 380 | /* Clear mask, so no surprise interrupts. */ |
384 | writeb(0, port->membase + MCFUART_UIMR); | 381 | writeb(0, port->membase + MCFUART_UIMR); |
@@ -424,7 +421,7 @@ static int mcf_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
424 | /* | 421 | /* |
425 | * Define the basic serial functions we support. | 422 | * Define the basic serial functions we support. |
426 | */ | 423 | */ |
427 | static struct uart_ops mcf_uart_ops = { | 424 | static const struct uart_ops mcf_uart_ops = { |
428 | .tx_empty = mcf_tx_empty, | 425 | .tx_empty = mcf_tx_empty, |
429 | .get_mctrl = mcf_get_mctrl, | 426 | .get_mctrl = mcf_get_mctrl, |
430 | .set_mctrl = mcf_set_mctrl, | 427 | .set_mctrl = mcf_set_mctrl, |
@@ -443,7 +440,7 @@ static struct uart_ops mcf_uart_ops = { | |||
443 | .verify_port = mcf_verify_port, | 440 | .verify_port = mcf_verify_port, |
444 | }; | 441 | }; |
445 | 442 | ||
446 | static struct mcf_uart mcf_ports[3]; | 443 | static struct mcf_uart mcf_ports[4]; |
447 | 444 | ||
448 | #define MCF_MAXPORTS ARRAY_SIZE(mcf_ports) | 445 | #define MCF_MAXPORTS ARRAY_SIZE(mcf_ports) |
449 | 446 | ||
@@ -602,7 +599,7 @@ static int __devinit mcf_probe(struct platform_device *pdev) | |||
602 | 599 | ||
603 | /****************************************************************************/ | 600 | /****************************************************************************/ |
604 | 601 | ||
605 | static int mcf_remove(struct platform_device *pdev) | 602 | static int __devexit mcf_remove(struct platform_device *pdev) |
606 | { | 603 | { |
607 | struct uart_port *port; | 604 | struct uart_port *port; |
608 | int i; | 605 | int i; |
diff --git a/drivers/serial/mfd.c b/drivers/serial/mfd.c new file mode 100644 index 000000000000..d40010a22ecd --- /dev/null +++ b/drivers/serial/mfd.c | |||
@@ -0,0 +1,1513 @@ | |||
1 | /* | ||
2 | * mfd.c: driver for High Speed UART device of Intel Medfield platform | ||
3 | * | ||
4 | * Refer pxa.c, 8250.c and some other drivers in drivers/serial/ | ||
5 | * | ||
6 | * (C) Copyright 2010 Intel Corporation | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * as published by the Free Software Foundation; version 2 | ||
11 | * of the License. | ||
12 | */ | ||
13 | |||
14 | /* Notes: | ||
15 | * 1. DMA channel allocation: 0/1 channel are assigned to port 0, | ||
16 | * 2/3 chan to port 1, 4/5 chan to port 3. Even number chans | ||
17 | * are used for RX, odd chans for TX | ||
18 | * | ||
19 | * 2. In A0 stepping, UART will not support TX half empty flag | ||
20 | * | ||
21 | * 3. The RI/DSR/DCD/DTR are not pinned out, DCD & DSR are always | ||
22 | * asserted, only when the HW is reset the DDCD and DDSR will | ||
23 | * be triggered | ||
24 | */ | ||
25 | |||
26 | #include <linux/module.h> | ||
27 | #include <linux/init.h> | ||
28 | #include <linux/console.h> | ||
29 | #include <linux/sysrq.h> | ||
30 | #include <linux/slab.h> | ||
31 | #include <linux/serial_reg.h> | ||
32 | #include <linux/circ_buf.h> | ||
33 | #include <linux/delay.h> | ||
34 | #include <linux/interrupt.h> | ||
35 | #include <linux/tty.h> | ||
36 | #include <linux/tty_flip.h> | ||
37 | #include <linux/serial_core.h> | ||
38 | #include <linux/serial_mfd.h> | ||
39 | #include <linux/dma-mapping.h> | ||
40 | #include <linux/pci.h> | ||
41 | #include <linux/io.h> | ||
42 | #include <linux/debugfs.h> | ||
43 | |||
44 | #define MFD_HSU_A0_STEPPING 1 | ||
45 | |||
46 | #define HSU_DMA_BUF_SIZE 2048 | ||
47 | |||
48 | #define chan_readl(chan, offset) readl(chan->reg + offset) | ||
49 | #define chan_writel(chan, offset, val) writel(val, chan->reg + offset) | ||
50 | |||
51 | #define mfd_readl(obj, offset) readl(obj->reg + offset) | ||
52 | #define mfd_writel(obj, offset, val) writel(val, obj->reg + offset) | ||
53 | |||
54 | #define HSU_DMA_TIMEOUT_CHECK_FREQ (HZ/10) | ||
55 | |||
56 | struct hsu_dma_buffer { | ||
57 | u8 *buf; | ||
58 | dma_addr_t dma_addr; | ||
59 | u32 dma_size; | ||
60 | u32 ofs; | ||
61 | }; | ||
62 | |||
63 | struct hsu_dma_chan { | ||
64 | u32 id; | ||
65 | enum dma_data_direction dirt; | ||
66 | struct uart_hsu_port *uport; | ||
67 | void __iomem *reg; | ||
68 | struct timer_list rx_timer; /* only needed by RX channel */ | ||
69 | }; | ||
70 | |||
71 | struct uart_hsu_port { | ||
72 | struct uart_port port; | ||
73 | unsigned char ier; | ||
74 | unsigned char lcr; | ||
75 | unsigned char mcr; | ||
76 | unsigned int lsr_break_flag; | ||
77 | char name[12]; | ||
78 | int index; | ||
79 | struct device *dev; | ||
80 | |||
81 | struct hsu_dma_chan *txc; | ||
82 | struct hsu_dma_chan *rxc; | ||
83 | struct hsu_dma_buffer txbuf; | ||
84 | struct hsu_dma_buffer rxbuf; | ||
85 | int use_dma; /* flag for DMA/PIO */ | ||
86 | int running; | ||
87 | int dma_tx_on; | ||
88 | }; | ||
89 | |||
90 | /* Top level data structure of HSU */ | ||
91 | struct hsu_port { | ||
92 | void __iomem *reg; | ||
93 | unsigned long paddr; | ||
94 | unsigned long iolen; | ||
95 | u32 irq; | ||
96 | |||
97 | struct uart_hsu_port port[3]; | ||
98 | struct hsu_dma_chan chans[10]; | ||
99 | |||
100 | struct dentry *debugfs; | ||
101 | }; | ||
102 | |||
103 | static inline unsigned int serial_in(struct uart_hsu_port *up, int offset) | ||
104 | { | ||
105 | unsigned int val; | ||
106 | |||
107 | if (offset > UART_MSR) { | ||
108 | offset <<= 2; | ||
109 | val = readl(up->port.membase + offset); | ||
110 | } else | ||
111 | val = (unsigned int)readb(up->port.membase + offset); | ||
112 | |||
113 | return val; | ||
114 | } | ||
115 | |||
116 | static inline void serial_out(struct uart_hsu_port *up, int offset, int value) | ||
117 | { | ||
118 | if (offset > UART_MSR) { | ||
119 | offset <<= 2; | ||
120 | writel(value, up->port.membase + offset); | ||
121 | } else { | ||
122 | unsigned char val = value & 0xff; | ||
123 | writeb(val, up->port.membase + offset); | ||
124 | } | ||
125 | } | ||
126 | |||
127 | #ifdef CONFIG_DEBUG_FS | ||
128 | |||
129 | #define HSU_REGS_BUFSIZE 1024 | ||
130 | |||
131 | static int hsu_show_regs_open(struct inode *inode, struct file *file) | ||
132 | { | ||
133 | file->private_data = inode->i_private; | ||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | static ssize_t port_show_regs(struct file *file, char __user *user_buf, | ||
138 | size_t count, loff_t *ppos) | ||
139 | { | ||
140 | struct uart_hsu_port *up = file->private_data; | ||
141 | char *buf; | ||
142 | u32 len = 0; | ||
143 | ssize_t ret; | ||
144 | |||
145 | buf = kzalloc(HSU_REGS_BUFSIZE, GFP_KERNEL); | ||
146 | if (!buf) | ||
147 | return 0; | ||
148 | |||
149 | len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, | ||
150 | "MFD HSU port[%d] regs:\n", up->index); | ||
151 | |||
152 | len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, | ||
153 | "=================================\n"); | ||
154 | len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, | ||
155 | "IER: \t\t0x%08x\n", serial_in(up, UART_IER)); | ||
156 | len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, | ||
157 | "IIR: \t\t0x%08x\n", serial_in(up, UART_IIR)); | ||
158 | len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, | ||
159 | "LCR: \t\t0x%08x\n", serial_in(up, UART_LCR)); | ||
160 | len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, | ||
161 | "MCR: \t\t0x%08x\n", serial_in(up, UART_MCR)); | ||
162 | len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, | ||
163 | "LSR: \t\t0x%08x\n", serial_in(up, UART_LSR)); | ||
164 | len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, | ||
165 | "MSR: \t\t0x%08x\n", serial_in(up, UART_MSR)); | ||
166 | len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, | ||
167 | "FOR: \t\t0x%08x\n", serial_in(up, UART_FOR)); | ||
168 | len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, | ||
169 | "PS: \t\t0x%08x\n", serial_in(up, UART_PS)); | ||
170 | len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, | ||
171 | "MUL: \t\t0x%08x\n", serial_in(up, UART_MUL)); | ||
172 | len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, | ||
173 | "DIV: \t\t0x%08x\n", serial_in(up, UART_DIV)); | ||
174 | |||
175 | if (len > HSU_REGS_BUFSIZE) | ||
176 | len = HSU_REGS_BUFSIZE; | ||
177 | |||
178 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
179 | kfree(buf); | ||
180 | return ret; | ||
181 | } | ||
182 | |||
183 | static ssize_t dma_show_regs(struct file *file, char __user *user_buf, | ||
184 | size_t count, loff_t *ppos) | ||
185 | { | ||
186 | struct hsu_dma_chan *chan = file->private_data; | ||
187 | char *buf; | ||
188 | u32 len = 0; | ||
189 | ssize_t ret; | ||
190 | |||
191 | buf = kzalloc(HSU_REGS_BUFSIZE, GFP_KERNEL); | ||
192 | if (!buf) | ||
193 | return 0; | ||
194 | |||
195 | len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, | ||
196 | "MFD HSU DMA channel [%d] regs:\n", chan->id); | ||
197 | |||
198 | len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, | ||
199 | "=================================\n"); | ||
200 | len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, | ||
201 | "CR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_CR)); | ||
202 | len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, | ||
203 | "DCR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_DCR)); | ||
204 | len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, | ||
205 | "BSR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_BSR)); | ||
206 | len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, | ||
207 | "MOTSR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_MOTSR)); | ||
208 | len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, | ||
209 | "D0SAR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_D0SAR)); | ||
210 | len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, | ||
211 | "D0TSR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_D0TSR)); | ||
212 | len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, | ||
213 | "D0SAR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_D1SAR)); | ||
214 | len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, | ||
215 | "D0TSR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_D1TSR)); | ||
216 | len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, | ||
217 | "D0SAR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_D2SAR)); | ||
218 | len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, | ||
219 | "D0TSR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_D2TSR)); | ||
220 | len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, | ||
221 | "D0SAR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_D3SAR)); | ||
222 | len += snprintf(buf + len, HSU_REGS_BUFSIZE - len, | ||
223 | "D0TSR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_D3TSR)); | ||
224 | |||
225 | if (len > HSU_REGS_BUFSIZE) | ||
226 | len = HSU_REGS_BUFSIZE; | ||
227 | |||
228 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
229 | kfree(buf); | ||
230 | return ret; | ||
231 | } | ||
232 | |||
233 | static const struct file_operations port_regs_ops = { | ||
234 | .owner = THIS_MODULE, | ||
235 | .open = hsu_show_regs_open, | ||
236 | .read = port_show_regs, | ||
237 | .llseek = default_llseek, | ||
238 | }; | ||
239 | |||
240 | static const struct file_operations dma_regs_ops = { | ||
241 | .owner = THIS_MODULE, | ||
242 | .open = hsu_show_regs_open, | ||
243 | .read = dma_show_regs, | ||
244 | .llseek = default_llseek, | ||
245 | }; | ||
246 | |||
247 | static int hsu_debugfs_init(struct hsu_port *hsu) | ||
248 | { | ||
249 | int i; | ||
250 | char name[32]; | ||
251 | |||
252 | hsu->debugfs = debugfs_create_dir("hsu", NULL); | ||
253 | if (!hsu->debugfs) | ||
254 | return -ENOMEM; | ||
255 | |||
256 | for (i = 0; i < 3; i++) { | ||
257 | snprintf(name, sizeof(name), "port_%d_regs", i); | ||
258 | debugfs_create_file(name, S_IFREG | S_IRUGO, | ||
259 | hsu->debugfs, (void *)(&hsu->port[i]), &port_regs_ops); | ||
260 | } | ||
261 | |||
262 | for (i = 0; i < 6; i++) { | ||
263 | snprintf(name, sizeof(name), "dma_chan_%d_regs", i); | ||
264 | debugfs_create_file(name, S_IFREG | S_IRUGO, | ||
265 | hsu->debugfs, (void *)&hsu->chans[i], &dma_regs_ops); | ||
266 | } | ||
267 | |||
268 | return 0; | ||
269 | } | ||
270 | |||
271 | static void hsu_debugfs_remove(struct hsu_port *hsu) | ||
272 | { | ||
273 | if (hsu->debugfs) | ||
274 | debugfs_remove_recursive(hsu->debugfs); | ||
275 | } | ||
276 | |||
277 | #else | ||
278 | static inline int hsu_debugfs_init(struct hsu_port *hsu) | ||
279 | { | ||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | static inline void hsu_debugfs_remove(struct hsu_port *hsu) | ||
284 | { | ||
285 | } | ||
286 | #endif /* CONFIG_DEBUG_FS */ | ||
287 | |||
288 | static void serial_hsu_enable_ms(struct uart_port *port) | ||
289 | { | ||
290 | struct uart_hsu_port *up = | ||
291 | container_of(port, struct uart_hsu_port, port); | ||
292 | |||
293 | up->ier |= UART_IER_MSI; | ||
294 | serial_out(up, UART_IER, up->ier); | ||
295 | } | ||
296 | |||
297 | void hsu_dma_tx(struct uart_hsu_port *up) | ||
298 | { | ||
299 | struct circ_buf *xmit = &up->port.state->xmit; | ||
300 | struct hsu_dma_buffer *dbuf = &up->txbuf; | ||
301 | int count; | ||
302 | |||
303 | /* test_and_set_bit may be better, but anyway it's in lock protected mode */ | ||
304 | if (up->dma_tx_on) | ||
305 | return; | ||
306 | |||
307 | /* Update the circ buf info */ | ||
308 | xmit->tail += dbuf->ofs; | ||
309 | xmit->tail &= UART_XMIT_SIZE - 1; | ||
310 | |||
311 | up->port.icount.tx += dbuf->ofs; | ||
312 | dbuf->ofs = 0; | ||
313 | |||
314 | /* Disable the channel */ | ||
315 | chan_writel(up->txc, HSU_CH_CR, 0x0); | ||
316 | |||
317 | if (!uart_circ_empty(xmit) && !uart_tx_stopped(&up->port)) { | ||
318 | dma_sync_single_for_device(up->port.dev, | ||
319 | dbuf->dma_addr, | ||
320 | dbuf->dma_size, | ||
321 | DMA_TO_DEVICE); | ||
322 | |||
323 | count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); | ||
324 | dbuf->ofs = count; | ||
325 | |||
326 | /* Reprogram the channel */ | ||
327 | chan_writel(up->txc, HSU_CH_D0SAR, dbuf->dma_addr + xmit->tail); | ||
328 | chan_writel(up->txc, HSU_CH_D0TSR, count); | ||
329 | |||
330 | /* Reenable the channel */ | ||
331 | chan_writel(up->txc, HSU_CH_DCR, 0x1 | ||
332 | | (0x1 << 8) | ||
333 | | (0x1 << 16) | ||
334 | | (0x1 << 24)); | ||
335 | up->dma_tx_on = 1; | ||
336 | chan_writel(up->txc, HSU_CH_CR, 0x1); | ||
337 | } | ||
338 | |||
339 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
340 | uart_write_wakeup(&up->port); | ||
341 | } | ||
342 | |||
343 | /* The buffer is already cache coherent */ | ||
344 | void hsu_dma_start_rx_chan(struct hsu_dma_chan *rxc, struct hsu_dma_buffer *dbuf) | ||
345 | { | ||
346 | dbuf->ofs = 0; | ||
347 | |||
348 | chan_writel(rxc, HSU_CH_BSR, 32); | ||
349 | chan_writel(rxc, HSU_CH_MOTSR, 4); | ||
350 | |||
351 | chan_writel(rxc, HSU_CH_D0SAR, dbuf->dma_addr); | ||
352 | chan_writel(rxc, HSU_CH_D0TSR, dbuf->dma_size); | ||
353 | chan_writel(rxc, HSU_CH_DCR, 0x1 | (0x1 << 8) | ||
354 | | (0x1 << 16) | ||
355 | | (0x1 << 24) /* timeout bit, see HSU Errata 1 */ | ||
356 | ); | ||
357 | chan_writel(rxc, HSU_CH_CR, 0x3); | ||
358 | |||
359 | mod_timer(&rxc->rx_timer, jiffies + HSU_DMA_TIMEOUT_CHECK_FREQ); | ||
360 | } | ||
361 | |||
362 | /* Protected by spin_lock_irqsave(port->lock) */ | ||
363 | static void serial_hsu_start_tx(struct uart_port *port) | ||
364 | { | ||
365 | struct uart_hsu_port *up = | ||
366 | container_of(port, struct uart_hsu_port, port); | ||
367 | |||
368 | if (up->use_dma) { | ||
369 | hsu_dma_tx(up); | ||
370 | } else if (!(up->ier & UART_IER_THRI)) { | ||
371 | up->ier |= UART_IER_THRI; | ||
372 | serial_out(up, UART_IER, up->ier); | ||
373 | } | ||
374 | } | ||
375 | |||
376 | static void serial_hsu_stop_tx(struct uart_port *port) | ||
377 | { | ||
378 | struct uart_hsu_port *up = | ||
379 | container_of(port, struct uart_hsu_port, port); | ||
380 | struct hsu_dma_chan *txc = up->txc; | ||
381 | |||
382 | if (up->use_dma) | ||
383 | chan_writel(txc, HSU_CH_CR, 0x0); | ||
384 | else if (up->ier & UART_IER_THRI) { | ||
385 | up->ier &= ~UART_IER_THRI; | ||
386 | serial_out(up, UART_IER, up->ier); | ||
387 | } | ||
388 | } | ||
389 | |||
390 | /* This is always called in spinlock protected mode, so | ||
391 | * modify timeout timer is safe here */ | ||
392 | void hsu_dma_rx(struct uart_hsu_port *up, u32 int_sts) | ||
393 | { | ||
394 | struct hsu_dma_buffer *dbuf = &up->rxbuf; | ||
395 | struct hsu_dma_chan *chan = up->rxc; | ||
396 | struct uart_port *port = &up->port; | ||
397 | struct tty_struct *tty = port->state->port.tty; | ||
398 | int count; | ||
399 | |||
400 | if (!tty) | ||
401 | return; | ||
402 | |||
403 | /* | ||
404 | * First need to know how many is already transferred, | ||
405 | * then check if its a timeout DMA irq, and return | ||
406 | * the trail bytes out, push them up and reenable the | ||
407 | * channel | ||
408 | */ | ||
409 | |||
410 | /* Timeout IRQ, need wait some time, see Errata 2 */ | ||
411 | if (int_sts & 0xf00) | ||
412 | udelay(2); | ||
413 | |||
414 | /* Stop the channel */ | ||
415 | chan_writel(chan, HSU_CH_CR, 0x0); | ||
416 | |||
417 | count = chan_readl(chan, HSU_CH_D0SAR) - dbuf->dma_addr; | ||
418 | if (!count) { | ||
419 | /* Restart the channel before we leave */ | ||
420 | chan_writel(chan, HSU_CH_CR, 0x3); | ||
421 | return; | ||
422 | } | ||
423 | del_timer(&chan->rx_timer); | ||
424 | |||
425 | dma_sync_single_for_cpu(port->dev, dbuf->dma_addr, | ||
426 | dbuf->dma_size, DMA_FROM_DEVICE); | ||
427 | |||
428 | /* | ||
429 | * Head will only wrap around when we recycle | ||
430 | * the DMA buffer, and when that happens, we | ||
431 | * explicitly set tail to 0. So head will | ||
432 | * always be greater than tail. | ||
433 | */ | ||
434 | tty_insert_flip_string(tty, dbuf->buf, count); | ||
435 | port->icount.rx += count; | ||
436 | |||
437 | dma_sync_single_for_device(up->port.dev, dbuf->dma_addr, | ||
438 | dbuf->dma_size, DMA_FROM_DEVICE); | ||
439 | |||
440 | /* Reprogram the channel */ | ||
441 | chan_writel(chan, HSU_CH_D0SAR, dbuf->dma_addr); | ||
442 | chan_writel(chan, HSU_CH_D0TSR, dbuf->dma_size); | ||
443 | chan_writel(chan, HSU_CH_DCR, 0x1 | ||
444 | | (0x1 << 8) | ||
445 | | (0x1 << 16) | ||
446 | | (0x1 << 24) /* timeout bit, see HSU Errata 1 */ | ||
447 | ); | ||
448 | tty_flip_buffer_push(tty); | ||
449 | |||
450 | chan_writel(chan, HSU_CH_CR, 0x3); | ||
451 | chan->rx_timer.expires = jiffies + HSU_DMA_TIMEOUT_CHECK_FREQ; | ||
452 | add_timer(&chan->rx_timer); | ||
453 | |||
454 | } | ||
455 | |||
456 | static void serial_hsu_stop_rx(struct uart_port *port) | ||
457 | { | ||
458 | struct uart_hsu_port *up = | ||
459 | container_of(port, struct uart_hsu_port, port); | ||
460 | struct hsu_dma_chan *chan = up->rxc; | ||
461 | |||
462 | if (up->use_dma) | ||
463 | chan_writel(chan, HSU_CH_CR, 0x2); | ||
464 | else { | ||
465 | up->ier &= ~UART_IER_RLSI; | ||
466 | up->port.read_status_mask &= ~UART_LSR_DR; | ||
467 | serial_out(up, UART_IER, up->ier); | ||
468 | } | ||
469 | } | ||
470 | |||
471 | static inline void receive_chars(struct uart_hsu_port *up, int *status) | ||
472 | { | ||
473 | struct tty_struct *tty = up->port.state->port.tty; | ||
474 | unsigned int ch, flag; | ||
475 | unsigned int max_count = 256; | ||
476 | |||
477 | if (!tty) | ||
478 | return; | ||
479 | |||
480 | do { | ||
481 | ch = serial_in(up, UART_RX); | ||
482 | flag = TTY_NORMAL; | ||
483 | up->port.icount.rx++; | ||
484 | |||
485 | if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE | | ||
486 | UART_LSR_FE | UART_LSR_OE))) { | ||
487 | |||
488 | dev_warn(up->dev, "We really rush into ERR/BI case" | ||
489 | "status = 0x%02x", *status); | ||
490 | /* For statistics only */ | ||
491 | if (*status & UART_LSR_BI) { | ||
492 | *status &= ~(UART_LSR_FE | UART_LSR_PE); | ||
493 | up->port.icount.brk++; | ||
494 | /* | ||
495 | * We do the SysRQ and SAK checking | ||
496 | * here because otherwise the break | ||
497 | * may get masked by ignore_status_mask | ||
498 | * or read_status_mask. | ||
499 | */ | ||
500 | if (uart_handle_break(&up->port)) | ||
501 | goto ignore_char; | ||
502 | } else if (*status & UART_LSR_PE) | ||
503 | up->port.icount.parity++; | ||
504 | else if (*status & UART_LSR_FE) | ||
505 | up->port.icount.frame++; | ||
506 | if (*status & UART_LSR_OE) | ||
507 | up->port.icount.overrun++; | ||
508 | |||
509 | /* Mask off conditions which should be ignored. */ | ||
510 | *status &= up->port.read_status_mask; | ||
511 | |||
512 | #ifdef CONFIG_SERIAL_MFD_HSU_CONSOLE | ||
513 | if (up->port.cons && | ||
514 | up->port.cons->index == up->port.line) { | ||
515 | /* Recover the break flag from console xmit */ | ||
516 | *status |= up->lsr_break_flag; | ||
517 | up->lsr_break_flag = 0; | ||
518 | } | ||
519 | #endif | ||
520 | if (*status & UART_LSR_BI) { | ||
521 | flag = TTY_BREAK; | ||
522 | } else if (*status & UART_LSR_PE) | ||
523 | flag = TTY_PARITY; | ||
524 | else if (*status & UART_LSR_FE) | ||
525 | flag = TTY_FRAME; | ||
526 | } | ||
527 | |||
528 | if (uart_handle_sysrq_char(&up->port, ch)) | ||
529 | goto ignore_char; | ||
530 | |||
531 | uart_insert_char(&up->port, *status, UART_LSR_OE, ch, flag); | ||
532 | ignore_char: | ||
533 | *status = serial_in(up, UART_LSR); | ||
534 | } while ((*status & UART_LSR_DR) && max_count--); | ||
535 | tty_flip_buffer_push(tty); | ||
536 | } | ||
537 | |||
538 | static void transmit_chars(struct uart_hsu_port *up) | ||
539 | { | ||
540 | struct circ_buf *xmit = &up->port.state->xmit; | ||
541 | int count; | ||
542 | |||
543 | if (up->port.x_char) { | ||
544 | serial_out(up, UART_TX, up->port.x_char); | ||
545 | up->port.icount.tx++; | ||
546 | up->port.x_char = 0; | ||
547 | return; | ||
548 | } | ||
549 | if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { | ||
550 | serial_hsu_stop_tx(&up->port); | ||
551 | return; | ||
552 | } | ||
553 | |||
554 | #ifndef MFD_HSU_A0_STEPPING | ||
555 | count = up->port.fifosize / 2; | ||
556 | #else | ||
557 | /* | ||
558 | * A0 only supports fully empty IRQ, and the first char written | ||
559 | * into it won't clear the EMPT bit, so we may need be cautious | ||
560 | * by useing a shorter buffer | ||
561 | */ | ||
562 | count = up->port.fifosize - 4; | ||
563 | #endif | ||
564 | do { | ||
565 | serial_out(up, UART_TX, xmit->buf[xmit->tail]); | ||
566 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
567 | |||
568 | up->port.icount.tx++; | ||
569 | if (uart_circ_empty(xmit)) | ||
570 | break; | ||
571 | } while (--count > 0); | ||
572 | |||
573 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
574 | uart_write_wakeup(&up->port); | ||
575 | |||
576 | if (uart_circ_empty(xmit)) | ||
577 | serial_hsu_stop_tx(&up->port); | ||
578 | } | ||
579 | |||
580 | static inline void check_modem_status(struct uart_hsu_port *up) | ||
581 | { | ||
582 | int status; | ||
583 | |||
584 | status = serial_in(up, UART_MSR); | ||
585 | |||
586 | if ((status & UART_MSR_ANY_DELTA) == 0) | ||
587 | return; | ||
588 | |||
589 | if (status & UART_MSR_TERI) | ||
590 | up->port.icount.rng++; | ||
591 | if (status & UART_MSR_DDSR) | ||
592 | up->port.icount.dsr++; | ||
593 | /* We may only get DDCD when HW init and reset */ | ||
594 | if (status & UART_MSR_DDCD) | ||
595 | uart_handle_dcd_change(&up->port, status & UART_MSR_DCD); | ||
596 | /* Will start/stop_tx accordingly */ | ||
597 | if (status & UART_MSR_DCTS) | ||
598 | uart_handle_cts_change(&up->port, status & UART_MSR_CTS); | ||
599 | |||
600 | wake_up_interruptible(&up->port.state->port.delta_msr_wait); | ||
601 | } | ||
602 | |||
603 | /* | ||
604 | * This handles the interrupt from one port. | ||
605 | */ | ||
606 | static irqreturn_t port_irq(int irq, void *dev_id) | ||
607 | { | ||
608 | struct uart_hsu_port *up = dev_id; | ||
609 | unsigned int iir, lsr; | ||
610 | unsigned long flags; | ||
611 | |||
612 | if (unlikely(!up->running)) | ||
613 | return IRQ_NONE; | ||
614 | |||
615 | spin_lock_irqsave(&up->port.lock, flags); | ||
616 | if (up->use_dma) { | ||
617 | lsr = serial_in(up, UART_LSR); | ||
618 | if (unlikely(lsr & (UART_LSR_BI | UART_LSR_PE | | ||
619 | UART_LSR_FE | UART_LSR_OE))) | ||
620 | dev_warn(up->dev, | ||
621 | "Got lsr irq while using DMA, lsr = 0x%2x\n", | ||
622 | lsr); | ||
623 | check_modem_status(up); | ||
624 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
625 | return IRQ_HANDLED; | ||
626 | } | ||
627 | |||
628 | iir = serial_in(up, UART_IIR); | ||
629 | if (iir & UART_IIR_NO_INT) { | ||
630 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
631 | return IRQ_NONE; | ||
632 | } | ||
633 | |||
634 | lsr = serial_in(up, UART_LSR); | ||
635 | if (lsr & UART_LSR_DR) | ||
636 | receive_chars(up, &lsr); | ||
637 | check_modem_status(up); | ||
638 | |||
639 | /* lsr will be renewed during the receive_chars */ | ||
640 | if (lsr & UART_LSR_THRE) | ||
641 | transmit_chars(up); | ||
642 | |||
643 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
644 | return IRQ_HANDLED; | ||
645 | } | ||
646 | |||
647 | static inline void dma_chan_irq(struct hsu_dma_chan *chan) | ||
648 | { | ||
649 | struct uart_hsu_port *up = chan->uport; | ||
650 | unsigned long flags; | ||
651 | u32 int_sts; | ||
652 | |||
653 | spin_lock_irqsave(&up->port.lock, flags); | ||
654 | |||
655 | if (!up->use_dma || !up->running) | ||
656 | goto exit; | ||
657 | |||
658 | /* | ||
659 | * No matter what situation, need read clear the IRQ status | ||
660 | * There is a bug, see Errata 5, HSD 2900918 | ||
661 | */ | ||
662 | int_sts = chan_readl(chan, HSU_CH_SR); | ||
663 | |||
664 | /* Rx channel */ | ||
665 | if (chan->dirt == DMA_FROM_DEVICE) | ||
666 | hsu_dma_rx(up, int_sts); | ||
667 | |||
668 | /* Tx channel */ | ||
669 | if (chan->dirt == DMA_TO_DEVICE) { | ||
670 | chan_writel(chan, HSU_CH_CR, 0x0); | ||
671 | up->dma_tx_on = 0; | ||
672 | hsu_dma_tx(up); | ||
673 | } | ||
674 | |||
675 | exit: | ||
676 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
677 | return; | ||
678 | } | ||
679 | |||
680 | static irqreturn_t dma_irq(int irq, void *dev_id) | ||
681 | { | ||
682 | struct hsu_port *hsu = dev_id; | ||
683 | u32 int_sts, i; | ||
684 | |||
685 | int_sts = mfd_readl(hsu, HSU_GBL_DMAISR); | ||
686 | |||
687 | /* Currently we only have 6 channels may be used */ | ||
688 | for (i = 0; i < 6; i++) { | ||
689 | if (int_sts & 0x1) | ||
690 | dma_chan_irq(&hsu->chans[i]); | ||
691 | int_sts >>= 1; | ||
692 | } | ||
693 | |||
694 | return IRQ_HANDLED; | ||
695 | } | ||
696 | |||
697 | static unsigned int serial_hsu_tx_empty(struct uart_port *port) | ||
698 | { | ||
699 | struct uart_hsu_port *up = | ||
700 | container_of(port, struct uart_hsu_port, port); | ||
701 | unsigned long flags; | ||
702 | unsigned int ret; | ||
703 | |||
704 | spin_lock_irqsave(&up->port.lock, flags); | ||
705 | ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; | ||
706 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
707 | |||
708 | return ret; | ||
709 | } | ||
710 | |||
711 | static unsigned int serial_hsu_get_mctrl(struct uart_port *port) | ||
712 | { | ||
713 | struct uart_hsu_port *up = | ||
714 | container_of(port, struct uart_hsu_port, port); | ||
715 | unsigned char status; | ||
716 | unsigned int ret; | ||
717 | |||
718 | status = serial_in(up, UART_MSR); | ||
719 | |||
720 | ret = 0; | ||
721 | if (status & UART_MSR_DCD) | ||
722 | ret |= TIOCM_CAR; | ||
723 | if (status & UART_MSR_RI) | ||
724 | ret |= TIOCM_RNG; | ||
725 | if (status & UART_MSR_DSR) | ||
726 | ret |= TIOCM_DSR; | ||
727 | if (status & UART_MSR_CTS) | ||
728 | ret |= TIOCM_CTS; | ||
729 | return ret; | ||
730 | } | ||
731 | |||
732 | static void serial_hsu_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
733 | { | ||
734 | struct uart_hsu_port *up = | ||
735 | container_of(port, struct uart_hsu_port, port); | ||
736 | unsigned char mcr = 0; | ||
737 | |||
738 | if (mctrl & TIOCM_RTS) | ||
739 | mcr |= UART_MCR_RTS; | ||
740 | if (mctrl & TIOCM_DTR) | ||
741 | mcr |= UART_MCR_DTR; | ||
742 | if (mctrl & TIOCM_OUT1) | ||
743 | mcr |= UART_MCR_OUT1; | ||
744 | if (mctrl & TIOCM_OUT2) | ||
745 | mcr |= UART_MCR_OUT2; | ||
746 | if (mctrl & TIOCM_LOOP) | ||
747 | mcr |= UART_MCR_LOOP; | ||
748 | |||
749 | mcr |= up->mcr; | ||
750 | |||
751 | serial_out(up, UART_MCR, mcr); | ||
752 | } | ||
753 | |||
754 | static void serial_hsu_break_ctl(struct uart_port *port, int break_state) | ||
755 | { | ||
756 | struct uart_hsu_port *up = | ||
757 | container_of(port, struct uart_hsu_port, port); | ||
758 | unsigned long flags; | ||
759 | |||
760 | spin_lock_irqsave(&up->port.lock, flags); | ||
761 | if (break_state == -1) | ||
762 | up->lcr |= UART_LCR_SBC; | ||
763 | else | ||
764 | up->lcr &= ~UART_LCR_SBC; | ||
765 | serial_out(up, UART_LCR, up->lcr); | ||
766 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
767 | } | ||
768 | |||
769 | /* | ||
770 | * What special to do: | ||
771 | * 1. chose the 64B fifo mode | ||
772 | * 2. make sure not to select half empty mode for A0 stepping | ||
773 | * 3. start dma or pio depends on configuration | ||
774 | * 4. we only allocate dma memory when needed | ||
775 | */ | ||
776 | static int serial_hsu_startup(struct uart_port *port) | ||
777 | { | ||
778 | struct uart_hsu_port *up = | ||
779 | container_of(port, struct uart_hsu_port, port); | ||
780 | unsigned long flags; | ||
781 | |||
782 | /* | ||
783 | * Clear the FIFO buffers and disable them. | ||
784 | * (they will be reenabled in set_termios()) | ||
785 | */ | ||
786 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); | ||
787 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | | ||
788 | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); | ||
789 | serial_out(up, UART_FCR, 0); | ||
790 | |||
791 | /* Clear the interrupt registers. */ | ||
792 | (void) serial_in(up, UART_LSR); | ||
793 | (void) serial_in(up, UART_RX); | ||
794 | (void) serial_in(up, UART_IIR); | ||
795 | (void) serial_in(up, UART_MSR); | ||
796 | |||
797 | /* Now, initialize the UART, default is 8n1 */ | ||
798 | serial_out(up, UART_LCR, UART_LCR_WLEN8); | ||
799 | |||
800 | spin_lock_irqsave(&up->port.lock, flags); | ||
801 | |||
802 | up->port.mctrl |= TIOCM_OUT2; | ||
803 | serial_hsu_set_mctrl(&up->port, up->port.mctrl); | ||
804 | |||
805 | /* | ||
806 | * Finally, enable interrupts. Note: Modem status interrupts | ||
807 | * are set via set_termios(), which will be occurring imminently | ||
808 | * anyway, so we don't enable them here. | ||
809 | */ | ||
810 | if (!up->use_dma) | ||
811 | up->ier = UART_IER_RLSI | UART_IER_RDI | UART_IER_RTOIE; | ||
812 | else | ||
813 | up->ier = 0; | ||
814 | serial_out(up, UART_IER, up->ier); | ||
815 | |||
816 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
817 | |||
818 | /* DMA init */ | ||
819 | if (up->use_dma) { | ||
820 | struct hsu_dma_buffer *dbuf; | ||
821 | struct circ_buf *xmit = &port->state->xmit; | ||
822 | |||
823 | up->dma_tx_on = 0; | ||
824 | |||
825 | /* First allocate the RX buffer */ | ||
826 | dbuf = &up->rxbuf; | ||
827 | dbuf->buf = kzalloc(HSU_DMA_BUF_SIZE, GFP_KERNEL); | ||
828 | if (!dbuf->buf) { | ||
829 | up->use_dma = 0; | ||
830 | goto exit; | ||
831 | } | ||
832 | dbuf->dma_addr = dma_map_single(port->dev, | ||
833 | dbuf->buf, | ||
834 | HSU_DMA_BUF_SIZE, | ||
835 | DMA_FROM_DEVICE); | ||
836 | dbuf->dma_size = HSU_DMA_BUF_SIZE; | ||
837 | |||
838 | /* Start the RX channel right now */ | ||
839 | hsu_dma_start_rx_chan(up->rxc, dbuf); | ||
840 | |||
841 | /* Next init the TX DMA */ | ||
842 | dbuf = &up->txbuf; | ||
843 | dbuf->buf = xmit->buf; | ||
844 | dbuf->dma_addr = dma_map_single(port->dev, | ||
845 | dbuf->buf, | ||
846 | UART_XMIT_SIZE, | ||
847 | DMA_TO_DEVICE); | ||
848 | dbuf->dma_size = UART_XMIT_SIZE; | ||
849 | |||
850 | /* This should not be changed all around */ | ||
851 | chan_writel(up->txc, HSU_CH_BSR, 32); | ||
852 | chan_writel(up->txc, HSU_CH_MOTSR, 4); | ||
853 | dbuf->ofs = 0; | ||
854 | } | ||
855 | |||
856 | exit: | ||
857 | /* And clear the interrupt registers again for luck. */ | ||
858 | (void) serial_in(up, UART_LSR); | ||
859 | (void) serial_in(up, UART_RX); | ||
860 | (void) serial_in(up, UART_IIR); | ||
861 | (void) serial_in(up, UART_MSR); | ||
862 | |||
863 | up->running = 1; | ||
864 | return 0; | ||
865 | } | ||
866 | |||
867 | static void serial_hsu_shutdown(struct uart_port *port) | ||
868 | { | ||
869 | struct uart_hsu_port *up = | ||
870 | container_of(port, struct uart_hsu_port, port); | ||
871 | unsigned long flags; | ||
872 | |||
873 | del_timer_sync(&up->rxc->rx_timer); | ||
874 | |||
875 | /* Disable interrupts from this port */ | ||
876 | up->ier = 0; | ||
877 | serial_out(up, UART_IER, 0); | ||
878 | up->running = 0; | ||
879 | |||
880 | spin_lock_irqsave(&up->port.lock, flags); | ||
881 | up->port.mctrl &= ~TIOCM_OUT2; | ||
882 | serial_hsu_set_mctrl(&up->port, up->port.mctrl); | ||
883 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
884 | |||
885 | /* Disable break condition and FIFOs */ | ||
886 | serial_out(up, UART_LCR, serial_in(up, UART_LCR) & ~UART_LCR_SBC); | ||
887 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | | ||
888 | UART_FCR_CLEAR_RCVR | | ||
889 | UART_FCR_CLEAR_XMIT); | ||
890 | serial_out(up, UART_FCR, 0); | ||
891 | } | ||
892 | |||
893 | static void | ||
894 | serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios, | ||
895 | struct ktermios *old) | ||
896 | { | ||
897 | struct uart_hsu_port *up = | ||
898 | container_of(port, struct uart_hsu_port, port); | ||
899 | struct tty_struct *tty = port->state->port.tty; | ||
900 | unsigned char cval, fcr = 0; | ||
901 | unsigned long flags; | ||
902 | unsigned int baud, quot; | ||
903 | u32 ps, mul; | ||
904 | |||
905 | switch (termios->c_cflag & CSIZE) { | ||
906 | case CS5: | ||
907 | cval = UART_LCR_WLEN5; | ||
908 | break; | ||
909 | case CS6: | ||
910 | cval = UART_LCR_WLEN6; | ||
911 | break; | ||
912 | case CS7: | ||
913 | cval = UART_LCR_WLEN7; | ||
914 | break; | ||
915 | default: | ||
916 | case CS8: | ||
917 | cval = UART_LCR_WLEN8; | ||
918 | break; | ||
919 | } | ||
920 | |||
921 | /* CMSPAR isn't supported by this driver */ | ||
922 | if (tty) | ||
923 | tty->termios->c_cflag &= ~CMSPAR; | ||
924 | |||
925 | if (termios->c_cflag & CSTOPB) | ||
926 | cval |= UART_LCR_STOP; | ||
927 | if (termios->c_cflag & PARENB) | ||
928 | cval |= UART_LCR_PARITY; | ||
929 | if (!(termios->c_cflag & PARODD)) | ||
930 | cval |= UART_LCR_EPAR; | ||
931 | |||
932 | /* | ||
933 | * The base clk is 50Mhz, and the baud rate come from: | ||
934 | * baud = 50M * MUL / (DIV * PS * DLAB) | ||
935 | * | ||
936 | * For those basic low baud rate we can get the direct | ||
937 | * scalar from 2746800, like 115200 = 2746800/24. For those | ||
938 | * higher baud rate, we handle them case by case, mainly by | ||
939 | * adjusting the MUL/PS registers, and DIV register is kept | ||
940 | * as default value 0x3d09 to make things simple | ||
941 | */ | ||
942 | baud = uart_get_baud_rate(port, termios, old, 0, 4000000); | ||
943 | |||
944 | quot = 1; | ||
945 | ps = 0x10; | ||
946 | mul = 0x3600; | ||
947 | switch (baud) { | ||
948 | case 3500000: | ||
949 | mul = 0x3345; | ||
950 | ps = 0xC; | ||
951 | break; | ||
952 | case 1843200: | ||
953 | mul = 0x2400; | ||
954 | break; | ||
955 | case 3000000: | ||
956 | case 2500000: | ||
957 | case 2000000: | ||
958 | case 1500000: | ||
959 | case 1000000: | ||
960 | case 500000: | ||
961 | /* mul/ps/quot = 0x9C4/0x10/0x1 will make a 500000 bps */ | ||
962 | mul = baud / 500000 * 0x9C4; | ||
963 | break; | ||
964 | default: | ||
965 | /* Use uart_get_divisor to get quot for other baud rates */ | ||
966 | quot = 0; | ||
967 | } | ||
968 | |||
969 | if (!quot) | ||
970 | quot = uart_get_divisor(port, baud); | ||
971 | |||
972 | if ((up->port.uartclk / quot) < (2400 * 16)) | ||
973 | fcr = UART_FCR_ENABLE_FIFO | UART_FCR_HSU_64_1B; | ||
974 | else if ((up->port.uartclk / quot) < (230400 * 16)) | ||
975 | fcr = UART_FCR_ENABLE_FIFO | UART_FCR_HSU_64_16B; | ||
976 | else | ||
977 | fcr = UART_FCR_ENABLE_FIFO | UART_FCR_HSU_64_32B; | ||
978 | |||
979 | fcr |= UART_FCR_HSU_64B_FIFO; | ||
980 | #ifdef MFD_HSU_A0_STEPPING | ||
981 | /* A0 doesn't support half empty IRQ */ | ||
982 | fcr |= UART_FCR_FULL_EMPT_TXI; | ||
983 | #endif | ||
984 | |||
985 | /* | ||
986 | * Ok, we're now changing the port state. Do it with | ||
987 | * interrupts disabled. | ||
988 | */ | ||
989 | spin_lock_irqsave(&up->port.lock, flags); | ||
990 | |||
991 | /* Update the per-port timeout */ | ||
992 | uart_update_timeout(port, termios->c_cflag, baud); | ||
993 | |||
994 | up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; | ||
995 | if (termios->c_iflag & INPCK) | ||
996 | up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE; | ||
997 | if (termios->c_iflag & (BRKINT | PARMRK)) | ||
998 | up->port.read_status_mask |= UART_LSR_BI; | ||
999 | |||
1000 | /* Characters to ignore */ | ||
1001 | up->port.ignore_status_mask = 0; | ||
1002 | if (termios->c_iflag & IGNPAR) | ||
1003 | up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; | ||
1004 | if (termios->c_iflag & IGNBRK) { | ||
1005 | up->port.ignore_status_mask |= UART_LSR_BI; | ||
1006 | /* | ||
1007 | * If we're ignoring parity and break indicators, | ||
1008 | * ignore overruns too (for real raw support). | ||
1009 | */ | ||
1010 | if (termios->c_iflag & IGNPAR) | ||
1011 | up->port.ignore_status_mask |= UART_LSR_OE; | ||
1012 | } | ||
1013 | |||
1014 | /* Ignore all characters if CREAD is not set */ | ||
1015 | if ((termios->c_cflag & CREAD) == 0) | ||
1016 | up->port.ignore_status_mask |= UART_LSR_DR; | ||
1017 | |||
1018 | /* | ||
1019 | * CTS flow control flag and modem status interrupts, disable | ||
1020 | * MSI by default | ||
1021 | */ | ||
1022 | up->ier &= ~UART_IER_MSI; | ||
1023 | if (UART_ENABLE_MS(&up->port, termios->c_cflag)) | ||
1024 | up->ier |= UART_IER_MSI; | ||
1025 | |||
1026 | serial_out(up, UART_IER, up->ier); | ||
1027 | |||
1028 | if (termios->c_cflag & CRTSCTS) | ||
1029 | up->mcr |= UART_MCR_AFE | UART_MCR_RTS; | ||
1030 | else | ||
1031 | up->mcr &= ~UART_MCR_AFE; | ||
1032 | |||
1033 | serial_out(up, UART_LCR, cval | UART_LCR_DLAB); /* set DLAB */ | ||
1034 | serial_out(up, UART_DLL, quot & 0xff); /* LS of divisor */ | ||
1035 | serial_out(up, UART_DLM, quot >> 8); /* MS of divisor */ | ||
1036 | serial_out(up, UART_LCR, cval); /* reset DLAB */ | ||
1037 | serial_out(up, UART_MUL, mul); /* set MUL */ | ||
1038 | serial_out(up, UART_PS, ps); /* set PS */ | ||
1039 | up->lcr = cval; /* Save LCR */ | ||
1040 | serial_hsu_set_mctrl(&up->port, up->port.mctrl); | ||
1041 | serial_out(up, UART_FCR, fcr); | ||
1042 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
1043 | } | ||
1044 | |||
1045 | static void | ||
1046 | serial_hsu_pm(struct uart_port *port, unsigned int state, | ||
1047 | unsigned int oldstate) | ||
1048 | { | ||
1049 | } | ||
1050 | |||
1051 | static void serial_hsu_release_port(struct uart_port *port) | ||
1052 | { | ||
1053 | } | ||
1054 | |||
1055 | static int serial_hsu_request_port(struct uart_port *port) | ||
1056 | { | ||
1057 | return 0; | ||
1058 | } | ||
1059 | |||
1060 | static void serial_hsu_config_port(struct uart_port *port, int flags) | ||
1061 | { | ||
1062 | struct uart_hsu_port *up = | ||
1063 | container_of(port, struct uart_hsu_port, port); | ||
1064 | up->port.type = PORT_MFD; | ||
1065 | } | ||
1066 | |||
1067 | static int | ||
1068 | serial_hsu_verify_port(struct uart_port *port, struct serial_struct *ser) | ||
1069 | { | ||
1070 | /* We don't want the core code to modify any port params */ | ||
1071 | return -EINVAL; | ||
1072 | } | ||
1073 | |||
1074 | static const char * | ||
1075 | serial_hsu_type(struct uart_port *port) | ||
1076 | { | ||
1077 | struct uart_hsu_port *up = | ||
1078 | container_of(port, struct uart_hsu_port, port); | ||
1079 | return up->name; | ||
1080 | } | ||
1081 | |||
1082 | /* Mainly for uart console use */ | ||
1083 | static struct uart_hsu_port *serial_hsu_ports[3]; | ||
1084 | static struct uart_driver serial_hsu_reg; | ||
1085 | |||
1086 | #ifdef CONFIG_SERIAL_MFD_HSU_CONSOLE | ||
1087 | |||
1088 | #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) | ||
1089 | |||
1090 | /* Wait for transmitter & holding register to empty */ | ||
1091 | static inline void wait_for_xmitr(struct uart_hsu_port *up) | ||
1092 | { | ||
1093 | unsigned int status, tmout = 1000; | ||
1094 | |||
1095 | /* Wait up to 1ms for the character to be sent. */ | ||
1096 | do { | ||
1097 | status = serial_in(up, UART_LSR); | ||
1098 | |||
1099 | if (status & UART_LSR_BI) | ||
1100 | up->lsr_break_flag = UART_LSR_BI; | ||
1101 | |||
1102 | if (--tmout == 0) | ||
1103 | break; | ||
1104 | udelay(1); | ||
1105 | } while (!(status & BOTH_EMPTY)); | ||
1106 | |||
1107 | /* Wait up to 1s for flow control if necessary */ | ||
1108 | if (up->port.flags & UPF_CONS_FLOW) { | ||
1109 | tmout = 1000000; | ||
1110 | while (--tmout && | ||
1111 | ((serial_in(up, UART_MSR) & UART_MSR_CTS) == 0)) | ||
1112 | udelay(1); | ||
1113 | } | ||
1114 | } | ||
1115 | |||
1116 | static void serial_hsu_console_putchar(struct uart_port *port, int ch) | ||
1117 | { | ||
1118 | struct uart_hsu_port *up = | ||
1119 | container_of(port, struct uart_hsu_port, port); | ||
1120 | |||
1121 | wait_for_xmitr(up); | ||
1122 | serial_out(up, UART_TX, ch); | ||
1123 | } | ||
1124 | |||
1125 | /* | ||
1126 | * Print a string to the serial port trying not to disturb | ||
1127 | * any possible real use of the port... | ||
1128 | * | ||
1129 | * The console_lock must be held when we get here. | ||
1130 | */ | ||
1131 | static void | ||
1132 | serial_hsu_console_write(struct console *co, const char *s, unsigned int count) | ||
1133 | { | ||
1134 | struct uart_hsu_port *up = serial_hsu_ports[co->index]; | ||
1135 | unsigned long flags; | ||
1136 | unsigned int ier; | ||
1137 | int locked = 1; | ||
1138 | |||
1139 | local_irq_save(flags); | ||
1140 | if (up->port.sysrq) | ||
1141 | locked = 0; | ||
1142 | else if (oops_in_progress) { | ||
1143 | locked = spin_trylock(&up->port.lock); | ||
1144 | } else | ||
1145 | spin_lock(&up->port.lock); | ||
1146 | |||
1147 | /* First save the IER then disable the interrupts */ | ||
1148 | ier = serial_in(up, UART_IER); | ||
1149 | serial_out(up, UART_IER, 0); | ||
1150 | |||
1151 | uart_console_write(&up->port, s, count, serial_hsu_console_putchar); | ||
1152 | |||
1153 | /* | ||
1154 | * Finally, wait for transmitter to become empty | ||
1155 | * and restore the IER | ||
1156 | */ | ||
1157 | wait_for_xmitr(up); | ||
1158 | serial_out(up, UART_IER, ier); | ||
1159 | |||
1160 | if (locked) | ||
1161 | spin_unlock(&up->port.lock); | ||
1162 | local_irq_restore(flags); | ||
1163 | } | ||
1164 | |||
1165 | static struct console serial_hsu_console; | ||
1166 | |||
1167 | static int __init | ||
1168 | serial_hsu_console_setup(struct console *co, char *options) | ||
1169 | { | ||
1170 | struct uart_hsu_port *up; | ||
1171 | int baud = 115200; | ||
1172 | int bits = 8; | ||
1173 | int parity = 'n'; | ||
1174 | int flow = 'n'; | ||
1175 | int ret; | ||
1176 | |||
1177 | if (co->index == -1 || co->index >= serial_hsu_reg.nr) | ||
1178 | co->index = 0; | ||
1179 | up = serial_hsu_ports[co->index]; | ||
1180 | if (!up) | ||
1181 | return -ENODEV; | ||
1182 | |||
1183 | if (options) | ||
1184 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
1185 | |||
1186 | ret = uart_set_options(&up->port, co, baud, parity, bits, flow); | ||
1187 | |||
1188 | return ret; | ||
1189 | } | ||
1190 | |||
1191 | static struct console serial_hsu_console = { | ||
1192 | .name = "ttyMFD", | ||
1193 | .write = serial_hsu_console_write, | ||
1194 | .device = uart_console_device, | ||
1195 | .setup = serial_hsu_console_setup, | ||
1196 | .flags = CON_PRINTBUFFER, | ||
1197 | .index = 2, | ||
1198 | .data = &serial_hsu_reg, | ||
1199 | }; | ||
1200 | #endif | ||
1201 | |||
1202 | struct uart_ops serial_hsu_pops = { | ||
1203 | .tx_empty = serial_hsu_tx_empty, | ||
1204 | .set_mctrl = serial_hsu_set_mctrl, | ||
1205 | .get_mctrl = serial_hsu_get_mctrl, | ||
1206 | .stop_tx = serial_hsu_stop_tx, | ||
1207 | .start_tx = serial_hsu_start_tx, | ||
1208 | .stop_rx = serial_hsu_stop_rx, | ||
1209 | .enable_ms = serial_hsu_enable_ms, | ||
1210 | .break_ctl = serial_hsu_break_ctl, | ||
1211 | .startup = serial_hsu_startup, | ||
1212 | .shutdown = serial_hsu_shutdown, | ||
1213 | .set_termios = serial_hsu_set_termios, | ||
1214 | .pm = serial_hsu_pm, | ||
1215 | .type = serial_hsu_type, | ||
1216 | .release_port = serial_hsu_release_port, | ||
1217 | .request_port = serial_hsu_request_port, | ||
1218 | .config_port = serial_hsu_config_port, | ||
1219 | .verify_port = serial_hsu_verify_port, | ||
1220 | }; | ||
1221 | |||
1222 | static struct uart_driver serial_hsu_reg = { | ||
1223 | .owner = THIS_MODULE, | ||
1224 | .driver_name = "MFD serial", | ||
1225 | .dev_name = "ttyMFD", | ||
1226 | .major = TTY_MAJOR, | ||
1227 | .minor = 128, | ||
1228 | .nr = 3, | ||
1229 | }; | ||
1230 | |||
1231 | #ifdef CONFIG_PM | ||
1232 | static int serial_hsu_suspend(struct pci_dev *pdev, pm_message_t state) | ||
1233 | { | ||
1234 | void *priv = pci_get_drvdata(pdev); | ||
1235 | struct uart_hsu_port *up; | ||
1236 | |||
1237 | /* Make sure this is not the internal dma controller */ | ||
1238 | if (priv && (pdev->device != 0x081E)) { | ||
1239 | up = priv; | ||
1240 | uart_suspend_port(&serial_hsu_reg, &up->port); | ||
1241 | } | ||
1242 | |||
1243 | pci_save_state(pdev); | ||
1244 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
1245 | return 0; | ||
1246 | } | ||
1247 | |||
1248 | static int serial_hsu_resume(struct pci_dev *pdev) | ||
1249 | { | ||
1250 | void *priv = pci_get_drvdata(pdev); | ||
1251 | struct uart_hsu_port *up; | ||
1252 | int ret; | ||
1253 | |||
1254 | pci_set_power_state(pdev, PCI_D0); | ||
1255 | pci_restore_state(pdev); | ||
1256 | |||
1257 | ret = pci_enable_device(pdev); | ||
1258 | if (ret) | ||
1259 | dev_warn(&pdev->dev, | ||
1260 | "HSU: can't re-enable device, try to continue\n"); | ||
1261 | |||
1262 | if (priv && (pdev->device != 0x081E)) { | ||
1263 | up = priv; | ||
1264 | uart_resume_port(&serial_hsu_reg, &up->port); | ||
1265 | } | ||
1266 | return 0; | ||
1267 | } | ||
1268 | #else | ||
1269 | #define serial_hsu_suspend NULL | ||
1270 | #define serial_hsu_resume NULL | ||
1271 | #endif | ||
1272 | |||
1273 | /* temp global pointer before we settle down on using one or four PCI dev */ | ||
1274 | static struct hsu_port *phsu; | ||
1275 | |||
1276 | static int serial_hsu_probe(struct pci_dev *pdev, | ||
1277 | const struct pci_device_id *ent) | ||
1278 | { | ||
1279 | struct uart_hsu_port *uport; | ||
1280 | int index, ret; | ||
1281 | |||
1282 | printk(KERN_INFO "HSU: found PCI Serial controller(ID: %04x:%04x)\n", | ||
1283 | pdev->vendor, pdev->device); | ||
1284 | |||
1285 | switch (pdev->device) { | ||
1286 | case 0x081B: | ||
1287 | index = 0; | ||
1288 | break; | ||
1289 | case 0x081C: | ||
1290 | index = 1; | ||
1291 | break; | ||
1292 | case 0x081D: | ||
1293 | index = 2; | ||
1294 | break; | ||
1295 | case 0x081E: | ||
1296 | /* internal DMA controller */ | ||
1297 | index = 3; | ||
1298 | break; | ||
1299 | default: | ||
1300 | dev_err(&pdev->dev, "HSU: out of index!"); | ||
1301 | return -ENODEV; | ||
1302 | } | ||
1303 | |||
1304 | ret = pci_enable_device(pdev); | ||
1305 | if (ret) | ||
1306 | return ret; | ||
1307 | |||
1308 | if (index == 3) { | ||
1309 | /* DMA controller */ | ||
1310 | ret = request_irq(pdev->irq, dma_irq, 0, "hsu_dma", phsu); | ||
1311 | if (ret) { | ||
1312 | dev_err(&pdev->dev, "can not get IRQ\n"); | ||
1313 | goto err_disable; | ||
1314 | } | ||
1315 | pci_set_drvdata(pdev, phsu); | ||
1316 | } else { | ||
1317 | /* UART port 0~2 */ | ||
1318 | uport = &phsu->port[index]; | ||
1319 | uport->port.irq = pdev->irq; | ||
1320 | uport->port.dev = &pdev->dev; | ||
1321 | uport->dev = &pdev->dev; | ||
1322 | |||
1323 | ret = request_irq(pdev->irq, port_irq, 0, uport->name, uport); | ||
1324 | if (ret) { | ||
1325 | dev_err(&pdev->dev, "can not get IRQ\n"); | ||
1326 | goto err_disable; | ||
1327 | } | ||
1328 | uart_add_one_port(&serial_hsu_reg, &uport->port); | ||
1329 | |||
1330 | #ifdef CONFIG_SERIAL_MFD_HSU_CONSOLE | ||
1331 | if (index == 2) { | ||
1332 | register_console(&serial_hsu_console); | ||
1333 | uport->port.cons = &serial_hsu_console; | ||
1334 | } | ||
1335 | #endif | ||
1336 | pci_set_drvdata(pdev, uport); | ||
1337 | } | ||
1338 | |||
1339 | return 0; | ||
1340 | |||
1341 | err_disable: | ||
1342 | pci_disable_device(pdev); | ||
1343 | return ret; | ||
1344 | } | ||
1345 | |||
1346 | static void hsu_dma_rx_timeout(unsigned long data) | ||
1347 | { | ||
1348 | struct hsu_dma_chan *chan = (void *)data; | ||
1349 | struct uart_hsu_port *up = chan->uport; | ||
1350 | struct hsu_dma_buffer *dbuf = &up->rxbuf; | ||
1351 | int count = 0; | ||
1352 | unsigned long flags; | ||
1353 | |||
1354 | spin_lock_irqsave(&up->port.lock, flags); | ||
1355 | |||
1356 | count = chan_readl(chan, HSU_CH_D0SAR) - dbuf->dma_addr; | ||
1357 | |||
1358 | if (!count) { | ||
1359 | mod_timer(&chan->rx_timer, jiffies + HSU_DMA_TIMEOUT_CHECK_FREQ); | ||
1360 | goto exit; | ||
1361 | } | ||
1362 | |||
1363 | hsu_dma_rx(up, 0); | ||
1364 | exit: | ||
1365 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
1366 | } | ||
1367 | |||
1368 | static void hsu_global_init(void) | ||
1369 | { | ||
1370 | struct hsu_port *hsu; | ||
1371 | struct uart_hsu_port *uport; | ||
1372 | struct hsu_dma_chan *dchan; | ||
1373 | int i, ret; | ||
1374 | |||
1375 | hsu = kzalloc(sizeof(struct hsu_port), GFP_KERNEL); | ||
1376 | if (!hsu) | ||
1377 | return; | ||
1378 | |||
1379 | /* Get basic io resource and map it */ | ||
1380 | hsu->paddr = 0xffa28000; | ||
1381 | hsu->iolen = 0x1000; | ||
1382 | |||
1383 | if (!(request_mem_region(hsu->paddr, hsu->iolen, "HSU global"))) | ||
1384 | pr_warning("HSU: error in request mem region\n"); | ||
1385 | |||
1386 | hsu->reg = ioremap_nocache((unsigned long)hsu->paddr, hsu->iolen); | ||
1387 | if (!hsu->reg) { | ||
1388 | pr_err("HSU: error in ioremap\n"); | ||
1389 | ret = -ENOMEM; | ||
1390 | goto err_free_region; | ||
1391 | } | ||
1392 | |||
1393 | /* Initialise the 3 UART ports */ | ||
1394 | uport = hsu->port; | ||
1395 | for (i = 0; i < 3; i++) { | ||
1396 | uport->port.type = PORT_MFD; | ||
1397 | uport->port.iotype = UPIO_MEM; | ||
1398 | uport->port.mapbase = (resource_size_t)hsu->paddr | ||
1399 | + HSU_PORT_REG_OFFSET | ||
1400 | + i * HSU_PORT_REG_LENGTH; | ||
1401 | uport->port.membase = hsu->reg + HSU_PORT_REG_OFFSET | ||
1402 | + i * HSU_PORT_REG_LENGTH; | ||
1403 | |||
1404 | sprintf(uport->name, "hsu_port%d", i); | ||
1405 | uport->port.fifosize = 64; | ||
1406 | uport->port.ops = &serial_hsu_pops; | ||
1407 | uport->port.line = i; | ||
1408 | uport->port.flags = UPF_IOREMAP; | ||
1409 | /* set the scalable maxim support rate to 2746800 bps */ | ||
1410 | uport->port.uartclk = 115200 * 24 * 16; | ||
1411 | |||
1412 | uport->running = 0; | ||
1413 | uport->txc = &hsu->chans[i * 2]; | ||
1414 | uport->rxc = &hsu->chans[i * 2 + 1]; | ||
1415 | |||
1416 | serial_hsu_ports[i] = uport; | ||
1417 | uport->index = i; | ||
1418 | uport++; | ||
1419 | } | ||
1420 | |||
1421 | /* Initialise 6 dma channels */ | ||
1422 | dchan = hsu->chans; | ||
1423 | for (i = 0; i < 6; i++) { | ||
1424 | dchan->id = i; | ||
1425 | dchan->dirt = (i & 0x1) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; | ||
1426 | dchan->uport = &hsu->port[i/2]; | ||
1427 | dchan->reg = hsu->reg + HSU_DMA_CHANS_REG_OFFSET + | ||
1428 | i * HSU_DMA_CHANS_REG_LENGTH; | ||
1429 | |||
1430 | /* Work around for RX */ | ||
1431 | if (dchan->dirt == DMA_FROM_DEVICE) { | ||
1432 | init_timer(&dchan->rx_timer); | ||
1433 | dchan->rx_timer.function = hsu_dma_rx_timeout; | ||
1434 | dchan->rx_timer.data = (unsigned long)dchan; | ||
1435 | } | ||
1436 | dchan++; | ||
1437 | } | ||
1438 | |||
1439 | phsu = hsu; | ||
1440 | hsu_debugfs_init(hsu); | ||
1441 | return; | ||
1442 | |||
1443 | err_free_region: | ||
1444 | release_mem_region(hsu->paddr, hsu->iolen); | ||
1445 | kfree(hsu); | ||
1446 | return; | ||
1447 | } | ||
1448 | |||
1449 | static void serial_hsu_remove(struct pci_dev *pdev) | ||
1450 | { | ||
1451 | void *priv = pci_get_drvdata(pdev); | ||
1452 | struct uart_hsu_port *up; | ||
1453 | |||
1454 | if (!priv) | ||
1455 | return; | ||
1456 | |||
1457 | /* For port 0/1/2, priv is the address of uart_hsu_port */ | ||
1458 | if (pdev->device != 0x081E) { | ||
1459 | up = priv; | ||
1460 | uart_remove_one_port(&serial_hsu_reg, &up->port); | ||
1461 | } | ||
1462 | |||
1463 | pci_set_drvdata(pdev, NULL); | ||
1464 | free_irq(pdev->irq, priv); | ||
1465 | pci_disable_device(pdev); | ||
1466 | } | ||
1467 | |||
1468 | /* First 3 are UART ports, and the 4th is the DMA */ | ||
1469 | static const struct pci_device_id pci_ids[] __devinitdata = { | ||
1470 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081B) }, | ||
1471 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081C) }, | ||
1472 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081D) }, | ||
1473 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081E) }, | ||
1474 | {}, | ||
1475 | }; | ||
1476 | |||
1477 | static struct pci_driver hsu_pci_driver = { | ||
1478 | .name = "HSU serial", | ||
1479 | .id_table = pci_ids, | ||
1480 | .probe = serial_hsu_probe, | ||
1481 | .remove = __devexit_p(serial_hsu_remove), | ||
1482 | .suspend = serial_hsu_suspend, | ||
1483 | .resume = serial_hsu_resume, | ||
1484 | }; | ||
1485 | |||
1486 | static int __init hsu_pci_init(void) | ||
1487 | { | ||
1488 | int ret; | ||
1489 | |||
1490 | hsu_global_init(); | ||
1491 | |||
1492 | ret = uart_register_driver(&serial_hsu_reg); | ||
1493 | if (ret) | ||
1494 | return ret; | ||
1495 | |||
1496 | return pci_register_driver(&hsu_pci_driver); | ||
1497 | } | ||
1498 | |||
1499 | static void __exit hsu_pci_exit(void) | ||
1500 | { | ||
1501 | pci_unregister_driver(&hsu_pci_driver); | ||
1502 | uart_unregister_driver(&serial_hsu_reg); | ||
1503 | |||
1504 | hsu_debugfs_remove(phsu); | ||
1505 | |||
1506 | kfree(phsu); | ||
1507 | } | ||
1508 | |||
1509 | module_init(hsu_pci_init); | ||
1510 | module_exit(hsu_pci_exit); | ||
1511 | |||
1512 | MODULE_LICENSE("GPL v2"); | ||
1513 | MODULE_ALIAS("platform:medfield-hsu"); | ||
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index abbd146c50d9..126ec7f568ec 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c | |||
@@ -29,39 +29,6 @@ | |||
29 | * kind, whether express or implied. | 29 | * kind, whether express or implied. |
30 | */ | 30 | */ |
31 | 31 | ||
32 | /* Platform device Usage : | ||
33 | * | ||
34 | * Since PSCs can have multiple function, the correct driver for each one | ||
35 | * is selected by calling mpc52xx_match_psc_function(...). The function | ||
36 | * handled by this driver is "uart". | ||
37 | * | ||
38 | * The driver init all necessary registers to place the PSC in uart mode without | ||
39 | * DCD. However, the pin multiplexing aren't changed and should be set either | ||
40 | * by the bootloader or in the platform init code. | ||
41 | * | ||
42 | * The idx field must be equal to the PSC index (e.g. 0 for PSC1, 1 for PSC2, | ||
43 | * and so on). So the PSC1 is mapped to /dev/ttyPSC0, PSC2 to /dev/ttyPSC1 and | ||
44 | * so on. But be warned, it's an ABSOLUTE REQUIREMENT ! This is needed mainly | ||
45 | * fpr the console code : without this 1:1 mapping, at early boot time, when we | ||
46 | * are parsing the kernel args console=ttyPSC?, we wouldn't know which PSC it | ||
47 | * will be mapped to. | ||
48 | */ | ||
49 | |||
50 | /* OF Platform device Usage : | ||
51 | * | ||
52 | * This driver is only used for PSCs configured in uart mode. The device | ||
53 | * tree will have a node for each PSC with "mpc52xx-psc-uart" in the compatible | ||
54 | * list. | ||
55 | * | ||
56 | * By default, PSC devices are enumerated in the order they are found. However | ||
57 | * a particular PSC number can be forces by adding 'device_no = <port#>' | ||
58 | * to the device node. | ||
59 | * | ||
60 | * The driver init all necessary registers to place the PSC in uart mode without | ||
61 | * DCD. However, the pin multiplexing aren't changed and should be set either | ||
62 | * by the bootloader or in the platform init code. | ||
63 | */ | ||
64 | |||
65 | #undef DEBUG | 32 | #undef DEBUG |
66 | 33 | ||
67 | #include <linux/device.h> | 34 | #include <linux/device.h> |
@@ -74,6 +41,7 @@ | |||
74 | #include <linux/io.h> | 41 | #include <linux/io.h> |
75 | #include <linux/of.h> | 42 | #include <linux/of.h> |
76 | #include <linux/of_platform.h> | 43 | #include <linux/of_platform.h> |
44 | #include <linux/clk.h> | ||
77 | 45 | ||
78 | #include <asm/mpc52xx.h> | 46 | #include <asm/mpc52xx.h> |
79 | #include <asm/mpc52xx_psc.h> | 47 | #include <asm/mpc52xx_psc.h> |
@@ -113,6 +81,7 @@ static void mpc52xx_uart_of_enumerate(void); | |||
113 | 81 | ||
114 | /* Forward declaration of the interruption handling routine */ | 82 | /* Forward declaration of the interruption handling routine */ |
115 | static irqreturn_t mpc52xx_uart_int(int irq, void *dev_id); | 83 | static irqreturn_t mpc52xx_uart_int(int irq, void *dev_id); |
84 | static irqreturn_t mpc5xxx_uart_process_int(struct uart_port *port); | ||
116 | 85 | ||
117 | 86 | ||
118 | /* Simple macro to test if a port is console or not. This one is taken | 87 | /* Simple macro to test if a port is console or not. This one is taken |
@@ -144,9 +113,26 @@ struct psc_ops { | |||
144 | unsigned char (*read_char)(struct uart_port *port); | 113 | unsigned char (*read_char)(struct uart_port *port); |
145 | void (*cw_disable_ints)(struct uart_port *port); | 114 | void (*cw_disable_ints)(struct uart_port *port); |
146 | void (*cw_restore_ints)(struct uart_port *port); | 115 | void (*cw_restore_ints)(struct uart_port *port); |
147 | unsigned long (*getuartclk)(void *p); | 116 | unsigned int (*set_baudrate)(struct uart_port *port, |
117 | struct ktermios *new, | ||
118 | struct ktermios *old); | ||
119 | int (*clock)(struct uart_port *port, int enable); | ||
120 | int (*fifoc_init)(void); | ||
121 | void (*fifoc_uninit)(void); | ||
122 | void (*get_irq)(struct uart_port *, struct device_node *); | ||
123 | irqreturn_t (*handle_irq)(struct uart_port *port); | ||
148 | }; | 124 | }; |
149 | 125 | ||
126 | /* setting the prescaler and divisor reg is common for all chips */ | ||
127 | static inline void mpc52xx_set_divisor(struct mpc52xx_psc __iomem *psc, | ||
128 | u16 prescaler, unsigned int divisor) | ||
129 | { | ||
130 | /* select prescaler */ | ||
131 | out_be16(&psc->mpc52xx_psc_clock_select, prescaler); | ||
132 | out_8(&psc->ctur, divisor >> 8); | ||
133 | out_8(&psc->ctlr, divisor & 0xff); | ||
134 | } | ||
135 | |||
150 | #ifdef CONFIG_PPC_MPC52xx | 136 | #ifdef CONFIG_PPC_MPC52xx |
151 | #define FIFO_52xx(port) ((struct mpc52xx_psc_fifo __iomem *)(PSC(port)+1)) | 137 | #define FIFO_52xx(port) ((struct mpc52xx_psc_fifo __iomem *)(PSC(port)+1)) |
152 | static void mpc52xx_psc_fifo_init(struct uart_port *port) | 138 | static void mpc52xx_psc_fifo_init(struct uart_port *port) |
@@ -154,9 +140,6 @@ static void mpc52xx_psc_fifo_init(struct uart_port *port) | |||
154 | struct mpc52xx_psc __iomem *psc = PSC(port); | 140 | struct mpc52xx_psc __iomem *psc = PSC(port); |
155 | struct mpc52xx_psc_fifo __iomem *fifo = FIFO_52xx(port); | 141 | struct mpc52xx_psc_fifo __iomem *fifo = FIFO_52xx(port); |
156 | 142 | ||
157 | /* /32 prescaler */ | ||
158 | out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); | ||
159 | |||
160 | out_8(&fifo->rfcntl, 0x00); | 143 | out_8(&fifo->rfcntl, 0x00); |
161 | out_be16(&fifo->rfalarm, 0x1ff); | 144 | out_be16(&fifo->rfalarm, 0x1ff); |
162 | out_8(&fifo->tfcntl, 0x07); | 145 | out_8(&fifo->tfcntl, 0x07); |
@@ -245,15 +228,59 @@ static void mpc52xx_psc_cw_restore_ints(struct uart_port *port) | |||
245 | out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask); | 228 | out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask); |
246 | } | 229 | } |
247 | 230 | ||
248 | /* Search for bus-frequency property in this node or a parent */ | 231 | static unsigned int mpc5200_psc_set_baudrate(struct uart_port *port, |
249 | static unsigned long mpc52xx_getuartclk(void *p) | 232 | struct ktermios *new, |
233 | struct ktermios *old) | ||
250 | { | 234 | { |
251 | /* | 235 | unsigned int baud; |
252 | * 5200 UARTs have a / 32 prescaler | 236 | unsigned int divisor; |
253 | * but the generic serial code assumes 16 | 237 | |
254 | * so return ipb freq / 2 | 238 | /* The 5200 has a fixed /32 prescaler, uartclk contains the ipb freq */ |
255 | */ | 239 | baud = uart_get_baud_rate(port, new, old, |
256 | return mpc5xxx_get_bus_frequency(p) / 2; | 240 | port->uartclk / (32 * 0xffff) + 1, |
241 | port->uartclk / 32); | ||
242 | divisor = (port->uartclk + 16 * baud) / (32 * baud); | ||
243 | |||
244 | /* enable the /32 prescaler and set the divisor */ | ||
245 | mpc52xx_set_divisor(PSC(port), 0xdd00, divisor); | ||
246 | return baud; | ||
247 | } | ||
248 | |||
249 | static unsigned int mpc5200b_psc_set_baudrate(struct uart_port *port, | ||
250 | struct ktermios *new, | ||
251 | struct ktermios *old) | ||
252 | { | ||
253 | unsigned int baud; | ||
254 | unsigned int divisor; | ||
255 | u16 prescaler; | ||
256 | |||
257 | /* The 5200B has a selectable /4 or /32 prescaler, uartclk contains the | ||
258 | * ipb freq */ | ||
259 | baud = uart_get_baud_rate(port, new, old, | ||
260 | port->uartclk / (32 * 0xffff) + 1, | ||
261 | port->uartclk / 4); | ||
262 | divisor = (port->uartclk + 2 * baud) / (4 * baud); | ||
263 | |||
264 | /* select the proper prescaler and set the divisor */ | ||
265 | if (divisor > 0xffff) { | ||
266 | divisor = (divisor + 4) / 8; | ||
267 | prescaler = 0xdd00; /* /32 */ | ||
268 | } else | ||
269 | prescaler = 0xff00; /* /4 */ | ||
270 | mpc52xx_set_divisor(PSC(port), prescaler, divisor); | ||
271 | return baud; | ||
272 | } | ||
273 | |||
274 | static void mpc52xx_psc_get_irq(struct uart_port *port, struct device_node *np) | ||
275 | { | ||
276 | port->irqflags = IRQF_DISABLED; | ||
277 | port->irq = irq_of_parse_and_map(np, 0); | ||
278 | } | ||
279 | |||
280 | /* 52xx specific interrupt handler. The caller holds the port lock */ | ||
281 | static irqreturn_t mpc52xx_psc_handle_irq(struct uart_port *port) | ||
282 | { | ||
283 | return mpc5xxx_uart_process_int(port); | ||
257 | } | 284 | } |
258 | 285 | ||
259 | static struct psc_ops mpc52xx_psc_ops = { | 286 | static struct psc_ops mpc52xx_psc_ops = { |
@@ -272,15 +299,54 @@ static struct psc_ops mpc52xx_psc_ops = { | |||
272 | .read_char = mpc52xx_psc_read_char, | 299 | .read_char = mpc52xx_psc_read_char, |
273 | .cw_disable_ints = mpc52xx_psc_cw_disable_ints, | 300 | .cw_disable_ints = mpc52xx_psc_cw_disable_ints, |
274 | .cw_restore_ints = mpc52xx_psc_cw_restore_ints, | 301 | .cw_restore_ints = mpc52xx_psc_cw_restore_ints, |
275 | .getuartclk = mpc52xx_getuartclk, | 302 | .set_baudrate = mpc5200_psc_set_baudrate, |
303 | .get_irq = mpc52xx_psc_get_irq, | ||
304 | .handle_irq = mpc52xx_psc_handle_irq, | ||
305 | }; | ||
306 | |||
307 | static struct psc_ops mpc5200b_psc_ops = { | ||
308 | .fifo_init = mpc52xx_psc_fifo_init, | ||
309 | .raw_rx_rdy = mpc52xx_psc_raw_rx_rdy, | ||
310 | .raw_tx_rdy = mpc52xx_psc_raw_tx_rdy, | ||
311 | .rx_rdy = mpc52xx_psc_rx_rdy, | ||
312 | .tx_rdy = mpc52xx_psc_tx_rdy, | ||
313 | .tx_empty = mpc52xx_psc_tx_empty, | ||
314 | .stop_rx = mpc52xx_psc_stop_rx, | ||
315 | .start_tx = mpc52xx_psc_start_tx, | ||
316 | .stop_tx = mpc52xx_psc_stop_tx, | ||
317 | .rx_clr_irq = mpc52xx_psc_rx_clr_irq, | ||
318 | .tx_clr_irq = mpc52xx_psc_tx_clr_irq, | ||
319 | .write_char = mpc52xx_psc_write_char, | ||
320 | .read_char = mpc52xx_psc_read_char, | ||
321 | .cw_disable_ints = mpc52xx_psc_cw_disable_ints, | ||
322 | .cw_restore_ints = mpc52xx_psc_cw_restore_ints, | ||
323 | .set_baudrate = mpc5200b_psc_set_baudrate, | ||
324 | .get_irq = mpc52xx_psc_get_irq, | ||
325 | .handle_irq = mpc52xx_psc_handle_irq, | ||
276 | }; | 326 | }; |
277 | 327 | ||
278 | #endif /* CONFIG_MPC52xx */ | 328 | #endif /* CONFIG_MPC52xx */ |
279 | 329 | ||
280 | #ifdef CONFIG_PPC_MPC512x | 330 | #ifdef CONFIG_PPC_MPC512x |
281 | #define FIFO_512x(port) ((struct mpc512x_psc_fifo __iomem *)(PSC(port)+1)) | 331 | #define FIFO_512x(port) ((struct mpc512x_psc_fifo __iomem *)(PSC(port)+1)) |
332 | |||
333 | /* PSC FIFO Controller for mpc512x */ | ||
334 | struct psc_fifoc { | ||
335 | u32 fifoc_cmd; | ||
336 | u32 fifoc_int; | ||
337 | u32 fifoc_dma; | ||
338 | u32 fifoc_axe; | ||
339 | u32 fifoc_debug; | ||
340 | }; | ||
341 | |||
342 | static struct psc_fifoc __iomem *psc_fifoc; | ||
343 | static unsigned int psc_fifoc_irq; | ||
344 | |||
282 | static void mpc512x_psc_fifo_init(struct uart_port *port) | 345 | static void mpc512x_psc_fifo_init(struct uart_port *port) |
283 | { | 346 | { |
347 | /* /32 prescaler */ | ||
348 | out_be16(&PSC(port)->mpc52xx_psc_clock_select, 0xdd00); | ||
349 | |||
284 | out_be32(&FIFO_512x(port)->txcmd, MPC512x_PSC_FIFO_RESET_SLICE); | 350 | out_be32(&FIFO_512x(port)->txcmd, MPC512x_PSC_FIFO_RESET_SLICE); |
285 | out_be32(&FIFO_512x(port)->txcmd, MPC512x_PSC_FIFO_ENABLE_SLICE); | 351 | out_be32(&FIFO_512x(port)->txcmd, MPC512x_PSC_FIFO_ENABLE_SLICE); |
286 | out_be32(&FIFO_512x(port)->txalarm, 1); | 352 | out_be32(&FIFO_512x(port)->txalarm, 1); |
@@ -388,9 +454,121 @@ static void mpc512x_psc_cw_restore_ints(struct uart_port *port) | |||
388 | out_be32(&FIFO_512x(port)->rximr, port->read_status_mask & 0x7f); | 454 | out_be32(&FIFO_512x(port)->rximr, port->read_status_mask & 0x7f); |
389 | } | 455 | } |
390 | 456 | ||
391 | static unsigned long mpc512x_getuartclk(void *p) | 457 | static unsigned int mpc512x_psc_set_baudrate(struct uart_port *port, |
458 | struct ktermios *new, | ||
459 | struct ktermios *old) | ||
392 | { | 460 | { |
393 | return mpc5xxx_get_bus_frequency(p); | 461 | unsigned int baud; |
462 | unsigned int divisor; | ||
463 | |||
464 | /* | ||
465 | * The "MPC5121e Microcontroller Reference Manual, Rev. 3" says on | ||
466 | * pg. 30-10 that the chip supports a /32 and a /10 prescaler. | ||
467 | * Furthermore, it states that "After reset, the prescaler by 10 | ||
468 | * for the UART mode is selected", but the reset register value is | ||
469 | * 0x0000 which means a /32 prescaler. This is wrong. | ||
470 | * | ||
471 | * In reality using /32 prescaler doesn't work, as it is not supported! | ||
472 | * Use /16 or /10 prescaler, see "MPC5121e Hardware Design Guide", | ||
473 | * Chapter 4.1 PSC in UART Mode. | ||
474 | * Calculate with a /16 prescaler here. | ||
475 | */ | ||
476 | |||
477 | /* uartclk contains the ips freq */ | ||
478 | baud = uart_get_baud_rate(port, new, old, | ||
479 | port->uartclk / (16 * 0xffff) + 1, | ||
480 | port->uartclk / 16); | ||
481 | divisor = (port->uartclk + 8 * baud) / (16 * baud); | ||
482 | |||
483 | /* enable the /16 prescaler and set the divisor */ | ||
484 | mpc52xx_set_divisor(PSC(port), 0xdd00, divisor); | ||
485 | return baud; | ||
486 | } | ||
487 | |||
488 | /* Init PSC FIFO Controller */ | ||
489 | static int __init mpc512x_psc_fifoc_init(void) | ||
490 | { | ||
491 | struct device_node *np; | ||
492 | |||
493 | np = of_find_compatible_node(NULL, NULL, | ||
494 | "fsl,mpc5121-psc-fifo"); | ||
495 | if (!np) { | ||
496 | pr_err("%s: Can't find FIFOC node\n", __func__); | ||
497 | return -ENODEV; | ||
498 | } | ||
499 | |||
500 | psc_fifoc = of_iomap(np, 0); | ||
501 | if (!psc_fifoc) { | ||
502 | pr_err("%s: Can't map FIFOC\n", __func__); | ||
503 | of_node_put(np); | ||
504 | return -ENODEV; | ||
505 | } | ||
506 | |||
507 | psc_fifoc_irq = irq_of_parse_and_map(np, 0); | ||
508 | of_node_put(np); | ||
509 | if (psc_fifoc_irq == NO_IRQ) { | ||
510 | pr_err("%s: Can't get FIFOC irq\n", __func__); | ||
511 | iounmap(psc_fifoc); | ||
512 | return -ENODEV; | ||
513 | } | ||
514 | |||
515 | return 0; | ||
516 | } | ||
517 | |||
518 | static void __exit mpc512x_psc_fifoc_uninit(void) | ||
519 | { | ||
520 | iounmap(psc_fifoc); | ||
521 | } | ||
522 | |||
523 | /* 512x specific interrupt handler. The caller holds the port lock */ | ||
524 | static irqreturn_t mpc512x_psc_handle_irq(struct uart_port *port) | ||
525 | { | ||
526 | unsigned long fifoc_int; | ||
527 | int psc_num; | ||
528 | |||
529 | /* Read pending PSC FIFOC interrupts */ | ||
530 | fifoc_int = in_be32(&psc_fifoc->fifoc_int); | ||
531 | |||
532 | /* Check if it is an interrupt for this port */ | ||
533 | psc_num = (port->mapbase & 0xf00) >> 8; | ||
534 | if (test_bit(psc_num, &fifoc_int) || | ||
535 | test_bit(psc_num + 16, &fifoc_int)) | ||
536 | return mpc5xxx_uart_process_int(port); | ||
537 | |||
538 | return IRQ_NONE; | ||
539 | } | ||
540 | |||
541 | static int mpc512x_psc_clock(struct uart_port *port, int enable) | ||
542 | { | ||
543 | struct clk *psc_clk; | ||
544 | int psc_num; | ||
545 | char clk_name[10]; | ||
546 | |||
547 | if (uart_console(port)) | ||
548 | return 0; | ||
549 | |||
550 | psc_num = (port->mapbase & 0xf00) >> 8; | ||
551 | snprintf(clk_name, sizeof(clk_name), "psc%d_clk", psc_num); | ||
552 | psc_clk = clk_get(port->dev, clk_name); | ||
553 | if (IS_ERR(psc_clk)) { | ||
554 | dev_err(port->dev, "Failed to get PSC clock entry!\n"); | ||
555 | return -ENODEV; | ||
556 | } | ||
557 | |||
558 | dev_dbg(port->dev, "%s %sable\n", clk_name, enable ? "en" : "dis"); | ||
559 | |||
560 | if (enable) | ||
561 | clk_enable(psc_clk); | ||
562 | else | ||
563 | clk_disable(psc_clk); | ||
564 | |||
565 | return 0; | ||
566 | } | ||
567 | |||
568 | static void mpc512x_psc_get_irq(struct uart_port *port, struct device_node *np) | ||
569 | { | ||
570 | port->irqflags = IRQF_SHARED; | ||
571 | port->irq = psc_fifoc_irq; | ||
394 | } | 572 | } |
395 | 573 | ||
396 | static struct psc_ops mpc512x_psc_ops = { | 574 | static struct psc_ops mpc512x_psc_ops = { |
@@ -409,7 +587,12 @@ static struct psc_ops mpc512x_psc_ops = { | |||
409 | .read_char = mpc512x_psc_read_char, | 587 | .read_char = mpc512x_psc_read_char, |
410 | .cw_disable_ints = mpc512x_psc_cw_disable_ints, | 588 | .cw_disable_ints = mpc512x_psc_cw_disable_ints, |
411 | .cw_restore_ints = mpc512x_psc_cw_restore_ints, | 589 | .cw_restore_ints = mpc512x_psc_cw_restore_ints, |
412 | .getuartclk = mpc512x_getuartclk, | 590 | .set_baudrate = mpc512x_psc_set_baudrate, |
591 | .clock = mpc512x_psc_clock, | ||
592 | .fifoc_init = mpc512x_psc_fifoc_init, | ||
593 | .fifoc_uninit = mpc512x_psc_fifoc_uninit, | ||
594 | .get_irq = mpc512x_psc_get_irq, | ||
595 | .handle_irq = mpc512x_psc_handle_irq, | ||
413 | }; | 596 | }; |
414 | #endif | 597 | #endif |
415 | 598 | ||
@@ -519,10 +702,15 @@ mpc52xx_uart_startup(struct uart_port *port) | |||
519 | struct mpc52xx_psc __iomem *psc = PSC(port); | 702 | struct mpc52xx_psc __iomem *psc = PSC(port); |
520 | int ret; | 703 | int ret; |
521 | 704 | ||
705 | if (psc_ops->clock) { | ||
706 | ret = psc_ops->clock(port, 1); | ||
707 | if (ret) | ||
708 | return ret; | ||
709 | } | ||
710 | |||
522 | /* Request IRQ */ | 711 | /* Request IRQ */ |
523 | ret = request_irq(port->irq, mpc52xx_uart_int, | 712 | ret = request_irq(port->irq, mpc52xx_uart_int, |
524 | IRQF_DISABLED | IRQF_SAMPLE_RANDOM, | 713 | port->irqflags, "mpc52xx_psc_uart", port); |
525 | "mpc52xx_psc_uart", port); | ||
526 | if (ret) | 714 | if (ret) |
527 | return ret; | 715 | return ret; |
528 | 716 | ||
@@ -553,6 +741,9 @@ mpc52xx_uart_shutdown(struct uart_port *port) | |||
553 | port->read_status_mask = 0; | 741 | port->read_status_mask = 0; |
554 | out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask); | 742 | out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask); |
555 | 743 | ||
744 | if (psc_ops->clock) | ||
745 | psc_ops->clock(port, 0); | ||
746 | |||
556 | /* Release interrupt */ | 747 | /* Release interrupt */ |
557 | free_irq(port->irq, port); | 748 | free_irq(port->irq, port); |
558 | } | 749 | } |
@@ -564,8 +755,8 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, | |||
564 | struct mpc52xx_psc __iomem *psc = PSC(port); | 755 | struct mpc52xx_psc __iomem *psc = PSC(port); |
565 | unsigned long flags; | 756 | unsigned long flags; |
566 | unsigned char mr1, mr2; | 757 | unsigned char mr1, mr2; |
567 | unsigned short ctr; | 758 | unsigned int j; |
568 | unsigned int j, baud, quot; | 759 | unsigned int baud; |
569 | 760 | ||
570 | /* Prepare what we're gonna write */ | 761 | /* Prepare what we're gonna write */ |
571 | mr1 = 0; | 762 | mr1 = 0; |
@@ -602,16 +793,9 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, | |||
602 | mr2 |= MPC52xx_PSC_MODE_TXCTS; | 793 | mr2 |= MPC52xx_PSC_MODE_TXCTS; |
603 | } | 794 | } |
604 | 795 | ||
605 | baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16); | ||
606 | quot = uart_get_divisor(port, baud); | ||
607 | ctr = quot & 0xffff; | ||
608 | |||
609 | /* Get the lock */ | 796 | /* Get the lock */ |
610 | spin_lock_irqsave(&port->lock, flags); | 797 | spin_lock_irqsave(&port->lock, flags); |
611 | 798 | ||
612 | /* Update the per-port timeout */ | ||
613 | uart_update_timeout(port, new->c_cflag, baud); | ||
614 | |||
615 | /* Do our best to flush TX & RX, so we don't lose anything */ | 799 | /* Do our best to flush TX & RX, so we don't lose anything */ |
616 | /* But we don't wait indefinitely ! */ | 800 | /* But we don't wait indefinitely ! */ |
617 | j = 5000000; /* Maximum wait */ | 801 | j = 5000000; /* Maximum wait */ |
@@ -635,8 +819,10 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, | |||
635 | out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1); | 819 | out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1); |
636 | out_8(&psc->mode, mr1); | 820 | out_8(&psc->mode, mr1); |
637 | out_8(&psc->mode, mr2); | 821 | out_8(&psc->mode, mr2); |
638 | out_8(&psc->ctur, ctr >> 8); | 822 | baud = psc_ops->set_baudrate(port, new, old); |
639 | out_8(&psc->ctlr, ctr & 0xff); | 823 | |
824 | /* Update the per-port timeout */ | ||
825 | uart_update_timeout(port, new->c_cflag, baud); | ||
640 | 826 | ||
641 | if (UART_ENABLE_MS(port, new->c_cflag)) | 827 | if (UART_ENABLE_MS(port, new->c_cflag)) |
642 | mpc52xx_uart_enable_ms(port); | 828 | mpc52xx_uart_enable_ms(port); |
@@ -652,7 +838,11 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, | |||
652 | static const char * | 838 | static const char * |
653 | mpc52xx_uart_type(struct uart_port *port) | 839 | mpc52xx_uart_type(struct uart_port *port) |
654 | { | 840 | { |
655 | return port->type == PORT_MPC52xx ? "MPC52xx PSC" : NULL; | 841 | /* |
842 | * We keep using PORT_MPC52xx for historic reasons although it applies | ||
843 | * for MPC512x, too, but print "MPC5xxx" to not irritate users | ||
844 | */ | ||
845 | return port->type == PORT_MPC52xx ? "MPC5xxx PSC" : NULL; | ||
656 | } | 846 | } |
657 | 847 | ||
658 | static void | 848 | static void |
@@ -705,7 +895,7 @@ mpc52xx_uart_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
705 | return -EINVAL; | 895 | return -EINVAL; |
706 | 896 | ||
707 | if ((ser->irq != port->irq) || | 897 | if ((ser->irq != port->irq) || |
708 | (ser->io_type != SERIAL_IO_MEM) || | 898 | (ser->io_type != UPIO_MEM) || |
709 | (ser->baud_base != port->uartclk) || | 899 | (ser->baud_base != port->uartclk) || |
710 | (ser->iomem_base != (void *)port->mapbase) || | 900 | (ser->iomem_base != (void *)port->mapbase) || |
711 | (ser->hub6 != 0)) | 901 | (ser->hub6 != 0)) |
@@ -745,7 +935,7 @@ static struct uart_ops mpc52xx_uart_ops = { | |||
745 | static inline int | 935 | static inline int |
746 | mpc52xx_uart_int_rx_chars(struct uart_port *port) | 936 | mpc52xx_uart_int_rx_chars(struct uart_port *port) |
747 | { | 937 | { |
748 | struct tty_struct *tty = port->info->port.tty; | 938 | struct tty_struct *tty = port->state->port.tty; |
749 | unsigned char ch, flag; | 939 | unsigned char ch, flag; |
750 | unsigned short status; | 940 | unsigned short status; |
751 | 941 | ||
@@ -812,7 +1002,7 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port) | |||
812 | static inline int | 1002 | static inline int |
813 | mpc52xx_uart_int_tx_chars(struct uart_port *port) | 1003 | mpc52xx_uart_int_tx_chars(struct uart_port *port) |
814 | { | 1004 | { |
815 | struct circ_buf *xmit = &port->info->xmit; | 1005 | struct circ_buf *xmit = &port->state->xmit; |
816 | 1006 | ||
817 | /* Process out of band chars */ | 1007 | /* Process out of band chars */ |
818 | if (port->x_char) { | 1008 | if (port->x_char) { |
@@ -851,15 +1041,12 @@ mpc52xx_uart_int_tx_chars(struct uart_port *port) | |||
851 | } | 1041 | } |
852 | 1042 | ||
853 | static irqreturn_t | 1043 | static irqreturn_t |
854 | mpc52xx_uart_int(int irq, void *dev_id) | 1044 | mpc5xxx_uart_process_int(struct uart_port *port) |
855 | { | 1045 | { |
856 | struct uart_port *port = dev_id; | ||
857 | unsigned long pass = ISR_PASS_LIMIT; | 1046 | unsigned long pass = ISR_PASS_LIMIT; |
858 | unsigned int keepgoing; | 1047 | unsigned int keepgoing; |
859 | u8 status; | 1048 | u8 status; |
860 | 1049 | ||
861 | spin_lock(&port->lock); | ||
862 | |||
863 | /* While we have stuff to do, we continue */ | 1050 | /* While we have stuff to do, we continue */ |
864 | do { | 1051 | do { |
865 | /* If we don't find anything to do, we stop */ | 1052 | /* If we don't find anything to do, we stop */ |
@@ -886,11 +1073,23 @@ mpc52xx_uart_int(int irq, void *dev_id) | |||
886 | 1073 | ||
887 | } while (keepgoing); | 1074 | } while (keepgoing); |
888 | 1075 | ||
889 | spin_unlock(&port->lock); | ||
890 | |||
891 | return IRQ_HANDLED; | 1076 | return IRQ_HANDLED; |
892 | } | 1077 | } |
893 | 1078 | ||
1079 | static irqreturn_t | ||
1080 | mpc52xx_uart_int(int irq, void *dev_id) | ||
1081 | { | ||
1082 | struct uart_port *port = dev_id; | ||
1083 | irqreturn_t ret; | ||
1084 | |||
1085 | spin_lock(&port->lock); | ||
1086 | |||
1087 | ret = psc_ops->handle_irq(port); | ||
1088 | |||
1089 | spin_unlock(&port->lock); | ||
1090 | |||
1091 | return ret; | ||
1092 | } | ||
894 | 1093 | ||
895 | /* ======================================================================== */ | 1094 | /* ======================================================================== */ |
896 | /* Console ( if applicable ) */ | 1095 | /* Console ( if applicable ) */ |
@@ -1007,7 +1206,7 @@ mpc52xx_console_setup(struct console *co, char *options) | |||
1007 | return ret; | 1206 | return ret; |
1008 | } | 1207 | } |
1009 | 1208 | ||
1010 | uartclk = psc_ops->getuartclk(np); | 1209 | uartclk = mpc5xxx_get_bus_frequency(np); |
1011 | if (uartclk == 0) { | 1210 | if (uartclk == 0) { |
1012 | pr_debug("Could not find uart clock frequency!\n"); | 1211 | pr_debug("Could not find uart clock frequency!\n"); |
1013 | return -EINVAL; | 1212 | return -EINVAL; |
@@ -1090,6 +1289,7 @@ static struct uart_driver mpc52xx_uart_driver = { | |||
1090 | 1289 | ||
1091 | static struct of_device_id mpc52xx_uart_of_match[] = { | 1290 | static struct of_device_id mpc52xx_uart_of_match[] = { |
1092 | #ifdef CONFIG_PPC_MPC52xx | 1291 | #ifdef CONFIG_PPC_MPC52xx |
1292 | { .compatible = "fsl,mpc5200b-psc-uart", .data = &mpc5200b_psc_ops, }, | ||
1093 | { .compatible = "fsl,mpc5200-psc-uart", .data = &mpc52xx_psc_ops, }, | 1293 | { .compatible = "fsl,mpc5200-psc-uart", .data = &mpc52xx_psc_ops, }, |
1094 | /* binding used by old lite5200 device trees: */ | 1294 | /* binding used by old lite5200 device trees: */ |
1095 | { .compatible = "mpc5200-psc-uart", .data = &mpc52xx_psc_ops, }, | 1295 | { .compatible = "mpc5200-psc-uart", .data = &mpc52xx_psc_ops, }, |
@@ -1103,7 +1303,7 @@ static struct of_device_id mpc52xx_uart_of_match[] = { | |||
1103 | }; | 1303 | }; |
1104 | 1304 | ||
1105 | static int __devinit | 1305 | static int __devinit |
1106 | mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) | 1306 | mpc52xx_uart_of_probe(struct platform_device *op, const struct of_device_id *match) |
1107 | { | 1307 | { |
1108 | int idx = -1; | 1308 | int idx = -1; |
1109 | unsigned int uartclk; | 1309 | unsigned int uartclk; |
@@ -1115,14 +1315,17 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) | |||
1115 | 1315 | ||
1116 | /* Check validity & presence */ | 1316 | /* Check validity & presence */ |
1117 | for (idx = 0; idx < MPC52xx_PSC_MAXNUM; idx++) | 1317 | for (idx = 0; idx < MPC52xx_PSC_MAXNUM; idx++) |
1118 | if (mpc52xx_uart_nodes[idx] == op->node) | 1318 | if (mpc52xx_uart_nodes[idx] == op->dev.of_node) |
1119 | break; | 1319 | break; |
1120 | if (idx >= MPC52xx_PSC_MAXNUM) | 1320 | if (idx >= MPC52xx_PSC_MAXNUM) |
1121 | return -EINVAL; | 1321 | return -EINVAL; |
1122 | pr_debug("Found %s assigned to ttyPSC%x\n", | 1322 | pr_debug("Found %s assigned to ttyPSC%x\n", |
1123 | mpc52xx_uart_nodes[idx]->full_name, idx); | 1323 | mpc52xx_uart_nodes[idx]->full_name, idx); |
1124 | 1324 | ||
1125 | uartclk = psc_ops->getuartclk(op->node); | 1325 | /* set the uart clock to the input clock of the psc, the different |
1326 | * prescalers are taken into account in the set_baudrate() methods | ||
1327 | * of the respective chip */ | ||
1328 | uartclk = mpc5xxx_get_bus_frequency(op->dev.of_node); | ||
1126 | if (uartclk == 0) { | 1329 | if (uartclk == 0) { |
1127 | dev_dbg(&op->dev, "Could not find uart clock frequency!\n"); | 1330 | dev_dbg(&op->dev, "Could not find uart clock frequency!\n"); |
1128 | return -EINVAL; | 1331 | return -EINVAL; |
@@ -1142,7 +1345,7 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) | |||
1142 | port->dev = &op->dev; | 1345 | port->dev = &op->dev; |
1143 | 1346 | ||
1144 | /* Search for IRQ and mapbase */ | 1347 | /* Search for IRQ and mapbase */ |
1145 | ret = of_address_to_resource(op->node, 0, &res); | 1348 | ret = of_address_to_resource(op->dev.of_node, 0, &res); |
1146 | if (ret) | 1349 | if (ret) |
1147 | return ret; | 1350 | return ret; |
1148 | 1351 | ||
@@ -1152,7 +1355,7 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) | |||
1152 | return -EINVAL; | 1355 | return -EINVAL; |
1153 | } | 1356 | } |
1154 | 1357 | ||
1155 | port->irq = irq_of_parse_and_map(op->node, 0); | 1358 | psc_ops->get_irq(port, op->dev.of_node); |
1156 | if (port->irq == NO_IRQ) { | 1359 | if (port->irq == NO_IRQ) { |
1157 | dev_dbg(&op->dev, "Could not get irq\n"); | 1360 | dev_dbg(&op->dev, "Could not get irq\n"); |
1158 | return -EINVAL; | 1361 | return -EINVAL; |
@@ -1163,32 +1366,28 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) | |||
1163 | 1366 | ||
1164 | /* Add the port to the uart sub-system */ | 1367 | /* Add the port to the uart sub-system */ |
1165 | ret = uart_add_one_port(&mpc52xx_uart_driver, port); | 1368 | ret = uart_add_one_port(&mpc52xx_uart_driver, port); |
1166 | if (ret) { | 1369 | if (ret) |
1167 | irq_dispose_mapping(port->irq); | ||
1168 | return ret; | 1370 | return ret; |
1169 | } | ||
1170 | 1371 | ||
1171 | dev_set_drvdata(&op->dev, (void *)port); | 1372 | dev_set_drvdata(&op->dev, (void *)port); |
1172 | return 0; | 1373 | return 0; |
1173 | } | 1374 | } |
1174 | 1375 | ||
1175 | static int | 1376 | static int |
1176 | mpc52xx_uart_of_remove(struct of_device *op) | 1377 | mpc52xx_uart_of_remove(struct platform_device *op) |
1177 | { | 1378 | { |
1178 | struct uart_port *port = dev_get_drvdata(&op->dev); | 1379 | struct uart_port *port = dev_get_drvdata(&op->dev); |
1179 | dev_set_drvdata(&op->dev, NULL); | 1380 | dev_set_drvdata(&op->dev, NULL); |
1180 | 1381 | ||
1181 | if (port) { | 1382 | if (port) |
1182 | uart_remove_one_port(&mpc52xx_uart_driver, port); | 1383 | uart_remove_one_port(&mpc52xx_uart_driver, port); |
1183 | irq_dispose_mapping(port->irq); | ||
1184 | } | ||
1185 | 1384 | ||
1186 | return 0; | 1385 | return 0; |
1187 | } | 1386 | } |
1188 | 1387 | ||
1189 | #ifdef CONFIG_PM | 1388 | #ifdef CONFIG_PM |
1190 | static int | 1389 | static int |
1191 | mpc52xx_uart_of_suspend(struct of_device *op, pm_message_t state) | 1390 | mpc52xx_uart_of_suspend(struct platform_device *op, pm_message_t state) |
1192 | { | 1391 | { |
1193 | struct uart_port *port = (struct uart_port *) dev_get_drvdata(&op->dev); | 1392 | struct uart_port *port = (struct uart_port *) dev_get_drvdata(&op->dev); |
1194 | 1393 | ||
@@ -1199,7 +1398,7 @@ mpc52xx_uart_of_suspend(struct of_device *op, pm_message_t state) | |||
1199 | } | 1398 | } |
1200 | 1399 | ||
1201 | static int | 1400 | static int |
1202 | mpc52xx_uart_of_resume(struct of_device *op) | 1401 | mpc52xx_uart_of_resume(struct platform_device *op) |
1203 | { | 1402 | { |
1204 | struct uart_port *port = (struct uart_port *) dev_get_drvdata(&op->dev); | 1403 | struct uart_port *port = (struct uart_port *) dev_get_drvdata(&op->dev); |
1205 | 1404 | ||
@@ -1255,15 +1454,16 @@ mpc52xx_uart_of_enumerate(void) | |||
1255 | MODULE_DEVICE_TABLE(of, mpc52xx_uart_of_match); | 1454 | MODULE_DEVICE_TABLE(of, mpc52xx_uart_of_match); |
1256 | 1455 | ||
1257 | static struct of_platform_driver mpc52xx_uart_of_driver = { | 1456 | static struct of_platform_driver mpc52xx_uart_of_driver = { |
1258 | .match_table = mpc52xx_uart_of_match, | ||
1259 | .probe = mpc52xx_uart_of_probe, | 1457 | .probe = mpc52xx_uart_of_probe, |
1260 | .remove = mpc52xx_uart_of_remove, | 1458 | .remove = mpc52xx_uart_of_remove, |
1261 | #ifdef CONFIG_PM | 1459 | #ifdef CONFIG_PM |
1262 | .suspend = mpc52xx_uart_of_suspend, | 1460 | .suspend = mpc52xx_uart_of_suspend, |
1263 | .resume = mpc52xx_uart_of_resume, | 1461 | .resume = mpc52xx_uart_of_resume, |
1264 | #endif | 1462 | #endif |
1265 | .driver = { | 1463 | .driver = { |
1266 | .name = "mpc52xx-psc-uart", | 1464 | .name = "mpc52xx-psc-uart", |
1465 | .owner = THIS_MODULE, | ||
1466 | .of_match_table = mpc52xx_uart_of_match, | ||
1267 | }, | 1467 | }, |
1268 | }; | 1468 | }; |
1269 | 1469 | ||
@@ -1288,6 +1488,15 @@ mpc52xx_uart_init(void) | |||
1288 | 1488 | ||
1289 | mpc52xx_uart_of_enumerate(); | 1489 | mpc52xx_uart_of_enumerate(); |
1290 | 1490 | ||
1491 | /* | ||
1492 | * Map the PSC FIFO Controller and init if on MPC512x. | ||
1493 | */ | ||
1494 | if (psc_ops && psc_ops->fifoc_init) { | ||
1495 | ret = psc_ops->fifoc_init(); | ||
1496 | if (ret) | ||
1497 | return ret; | ||
1498 | } | ||
1499 | |||
1291 | ret = of_register_platform_driver(&mpc52xx_uart_of_driver); | 1500 | ret = of_register_platform_driver(&mpc52xx_uart_of_driver); |
1292 | if (ret) { | 1501 | if (ret) { |
1293 | printk(KERN_ERR "%s: of_register_platform_driver failed (%i)\n", | 1502 | printk(KERN_ERR "%s: of_register_platform_driver failed (%i)\n", |
@@ -1302,6 +1511,9 @@ mpc52xx_uart_init(void) | |||
1302 | static void __exit | 1511 | static void __exit |
1303 | mpc52xx_uart_exit(void) | 1512 | mpc52xx_uart_exit(void) |
1304 | { | 1513 | { |
1514 | if (psc_ops->fifoc_uninit) | ||
1515 | psc_ops->fifoc_uninit(); | ||
1516 | |||
1305 | of_unregister_platform_driver(&mpc52xx_uart_of_driver); | 1517 | of_unregister_platform_driver(&mpc52xx_uart_of_driver); |
1306 | uart_unregister_driver(&mpc52xx_uart_driver); | 1518 | uart_unregister_driver(&mpc52xx_uart_driver); |
1307 | } | 1519 | } |
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c index 61d3ade5286c..6a9c6605666a 100644 --- a/drivers/serial/mpsc.c +++ b/drivers/serial/mpsc.c | |||
@@ -70,6 +70,7 @@ | |||
70 | #include <linux/dma-mapping.h> | 70 | #include <linux/dma-mapping.h> |
71 | #include <linux/mv643xx.h> | 71 | #include <linux/mv643xx.h> |
72 | #include <linux/platform_device.h> | 72 | #include <linux/platform_device.h> |
73 | #include <linux/gfp.h> | ||
73 | 74 | ||
74 | #include <asm/io.h> | 75 | #include <asm/io.h> |
75 | #include <asm/irq.h> | 76 | #include <asm/irq.h> |
@@ -936,7 +937,7 @@ static int serial_polled; | |||
936 | static int mpsc_rx_intr(struct mpsc_port_info *pi) | 937 | static int mpsc_rx_intr(struct mpsc_port_info *pi) |
937 | { | 938 | { |
938 | struct mpsc_rx_desc *rxre; | 939 | struct mpsc_rx_desc *rxre; |
939 | struct tty_struct *tty = pi->port.info->port.tty; | 940 | struct tty_struct *tty = pi->port.state->port.tty; |
940 | u32 cmdstat, bytes_in, i; | 941 | u32 cmdstat, bytes_in, i; |
941 | int rc = 0; | 942 | int rc = 0; |
942 | u8 *bp; | 943 | u8 *bp; |
@@ -1109,7 +1110,7 @@ static void mpsc_setup_tx_desc(struct mpsc_port_info *pi, u32 count, u32 intr) | |||
1109 | 1110 | ||
1110 | static void mpsc_copy_tx_data(struct mpsc_port_info *pi) | 1111 | static void mpsc_copy_tx_data(struct mpsc_port_info *pi) |
1111 | { | 1112 | { |
1112 | struct circ_buf *xmit = &pi->port.info->xmit; | 1113 | struct circ_buf *xmit = &pi->port.state->xmit; |
1113 | u8 *bp; | 1114 | u8 *bp; |
1114 | u32 i; | 1115 | u32 i; |
1115 | 1116 | ||
@@ -2070,6 +2071,7 @@ static int mpsc_drv_probe(struct platform_device *dev) | |||
2070 | 2071 | ||
2071 | if (!(rc = mpsc_drv_map_regs(pi, dev))) { | 2072 | if (!(rc = mpsc_drv_map_regs(pi, dev))) { |
2072 | mpsc_drv_get_platform_data(pi, dev, dev->id); | 2073 | mpsc_drv_get_platform_data(pi, dev, dev->id); |
2074 | pi->port.dev = &dev->dev; | ||
2073 | 2075 | ||
2074 | if (!(rc = mpsc_make_ready(pi))) { | 2076 | if (!(rc = mpsc_make_ready(pi))) { |
2075 | spin_lock_init(&pi->tx_lock); | 2077 | spin_lock_init(&pi->tx_lock); |
diff --git a/drivers/serial/mrst_max3110.c b/drivers/serial/mrst_max3110.c new file mode 100644 index 000000000000..b62857bf2fdb --- /dev/null +++ b/drivers/serial/mrst_max3110.c | |||
@@ -0,0 +1,919 @@ | |||
1 | /* | ||
2 | * mrst_max3110.c - spi uart protocol driver for Maxim 3110 | ||
3 | * | ||
4 | * Copyright (c) 2008-2010, Intel Corporation. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along with | ||
16 | * this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | */ | ||
19 | |||
20 | /* | ||
21 | * Note: | ||
22 | * 1. From Max3110 spec, the Rx FIFO has 8 words, while the Tx FIFO only has | ||
23 | * 1 word. If SPI master controller doesn't support sclk frequency change, | ||
24 | * then the char need be sent out one by one with some delay | ||
25 | * | ||
26 | * 2. Currently only RX availabe interrrupt is used, no need for waiting TXE | ||
27 | * interrupt for a low speed UART device | ||
28 | */ | ||
29 | |||
30 | #include <linux/module.h> | ||
31 | #include <linux/ioport.h> | ||
32 | #include <linux/irq.h> | ||
33 | #include <linux/init.h> | ||
34 | #include <linux/console.h> | ||
35 | #include <linux/tty.h> | ||
36 | #include <linux/tty_flip.h> | ||
37 | #include <linux/serial_core.h> | ||
38 | #include <linux/serial_reg.h> | ||
39 | |||
40 | #include <linux/kthread.h> | ||
41 | #include <linux/spi/spi.h> | ||
42 | |||
43 | #include "mrst_max3110.h" | ||
44 | |||
45 | #define PR_FMT "mrst_max3110: " | ||
46 | |||
47 | #define UART_TX_NEEDED 1 | ||
48 | #define CON_TX_NEEDED 2 | ||
49 | #define BIT_IRQ_PENDING 3 | ||
50 | |||
51 | struct uart_max3110 { | ||
52 | struct uart_port port; | ||
53 | struct spi_device *spi; | ||
54 | char name[24]; | ||
55 | |||
56 | wait_queue_head_t wq; | ||
57 | struct task_struct *main_thread; | ||
58 | struct task_struct *read_thread; | ||
59 | struct mutex thread_mutex;; | ||
60 | |||
61 | u32 baud; | ||
62 | u16 cur_conf; | ||
63 | u8 clock; | ||
64 | u8 parity, word_7bits; | ||
65 | u16 irq; | ||
66 | |||
67 | unsigned long uart_flags; | ||
68 | |||
69 | /* console related */ | ||
70 | struct circ_buf con_xmit; | ||
71 | }; | ||
72 | |||
73 | /* global data structure, may need be removed */ | ||
74 | static struct uart_max3110 *pmax; | ||
75 | |||
76 | static void receive_chars(struct uart_max3110 *max, | ||
77 | unsigned char *str, int len); | ||
78 | static int max3110_read_multi(struct uart_max3110 *max, u8 *buf); | ||
79 | static void max3110_con_receive(struct uart_max3110 *max); | ||
80 | |||
81 | static int max3110_write_then_read(struct uart_max3110 *max, | ||
82 | const void *txbuf, void *rxbuf, unsigned len, int always_fast) | ||
83 | { | ||
84 | struct spi_device *spi = max->spi; | ||
85 | struct spi_message message; | ||
86 | struct spi_transfer x; | ||
87 | int ret; | ||
88 | |||
89 | spi_message_init(&message); | ||
90 | memset(&x, 0, sizeof x); | ||
91 | x.len = len; | ||
92 | x.tx_buf = txbuf; | ||
93 | x.rx_buf = rxbuf; | ||
94 | spi_message_add_tail(&x, &message); | ||
95 | |||
96 | if (always_fast) | ||
97 | x.speed_hz = spi->max_speed_hz; | ||
98 | else if (max->baud) | ||
99 | x.speed_hz = max->baud; | ||
100 | |||
101 | /* Do the i/o */ | ||
102 | ret = spi_sync(spi, &message); | ||
103 | return ret; | ||
104 | } | ||
105 | |||
106 | /* Write a 16b word to the device */ | ||
107 | static int max3110_out(struct uart_max3110 *max, const u16 out) | ||
108 | { | ||
109 | void *buf; | ||
110 | u16 *obuf, *ibuf; | ||
111 | u8 ch; | ||
112 | int ret; | ||
113 | |||
114 | buf = kzalloc(8, GFP_KERNEL | GFP_DMA); | ||
115 | if (!buf) | ||
116 | return -ENOMEM; | ||
117 | |||
118 | obuf = buf; | ||
119 | ibuf = buf + 4; | ||
120 | *obuf = out; | ||
121 | ret = max3110_write_then_read(max, obuf, ibuf, 2, 1); | ||
122 | if (ret) { | ||
123 | pr_warning(PR_FMT "%s(): get err msg %d when sending 0x%x\n", | ||
124 | __func__, ret, out); | ||
125 | goto exit; | ||
126 | } | ||
127 | |||
128 | /* If some valid data is read back */ | ||
129 | if (*ibuf & MAX3110_READ_DATA_AVAILABLE) { | ||
130 | ch = *ibuf & 0xff; | ||
131 | receive_chars(max, &ch, 1); | ||
132 | } | ||
133 | |||
134 | exit: | ||
135 | kfree(buf); | ||
136 | return ret; | ||
137 | } | ||
138 | |||
139 | /* | ||
140 | * This is usually used to read data from SPIC RX FIFO, which doesn't | ||
141 | * need any delay like flushing character out. | ||
142 | * | ||
143 | * Return how many valide bytes are read back | ||
144 | */ | ||
145 | static int max3110_read_multi(struct uart_max3110 *max, u8 *rxbuf) | ||
146 | { | ||
147 | void *buf; | ||
148 | u16 *obuf, *ibuf; | ||
149 | u8 *pbuf, valid_str[M3110_RX_FIFO_DEPTH]; | ||
150 | int i, j, blen; | ||
151 | |||
152 | blen = M3110_RX_FIFO_DEPTH * sizeof(u16); | ||
153 | buf = kzalloc(blen * 2, GFP_KERNEL | GFP_DMA); | ||
154 | if (!buf) { | ||
155 | pr_warning(PR_FMT "%s(): fail to alloc dma buffer\n", __func__); | ||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | /* tx/rx always have the same length */ | ||
160 | obuf = buf; | ||
161 | ibuf = buf + blen; | ||
162 | |||
163 | if (max3110_write_then_read(max, obuf, ibuf, blen, 1)) { | ||
164 | kfree(buf); | ||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | /* If caller doesn't provide a buffer, then handle received char */ | ||
169 | pbuf = rxbuf ? rxbuf : valid_str; | ||
170 | |||
171 | for (i = 0, j = 0; i < M3110_RX_FIFO_DEPTH; i++) { | ||
172 | if (ibuf[i] & MAX3110_READ_DATA_AVAILABLE) | ||
173 | pbuf[j++] = ibuf[i] & 0xff; | ||
174 | } | ||
175 | |||
176 | if (j && (pbuf == valid_str)) | ||
177 | receive_chars(max, valid_str, j); | ||
178 | |||
179 | kfree(buf); | ||
180 | return j; | ||
181 | } | ||
182 | |||
183 | static void serial_m3110_con_putchar(struct uart_port *port, int ch) | ||
184 | { | ||
185 | struct uart_max3110 *max = | ||
186 | container_of(port, struct uart_max3110, port); | ||
187 | struct circ_buf *xmit = &max->con_xmit; | ||
188 | |||
189 | if (uart_circ_chars_free(xmit)) { | ||
190 | xmit->buf[xmit->head] = (char)ch; | ||
191 | xmit->head = (xmit->head + 1) & (PAGE_SIZE - 1); | ||
192 | } | ||
193 | } | ||
194 | |||
195 | /* | ||
196 | * Print a string to the serial port trying not to disturb | ||
197 | * any possible real use of the port... | ||
198 | * | ||
199 | * The console_lock must be held when we get here. | ||
200 | */ | ||
201 | static void serial_m3110_con_write(struct console *co, | ||
202 | const char *s, unsigned int count) | ||
203 | { | ||
204 | if (!pmax) | ||
205 | return; | ||
206 | |||
207 | uart_console_write(&pmax->port, s, count, serial_m3110_con_putchar); | ||
208 | |||
209 | if (!test_and_set_bit(CON_TX_NEEDED, &pmax->uart_flags)) | ||
210 | wake_up_process(pmax->main_thread); | ||
211 | } | ||
212 | |||
213 | static int __init | ||
214 | serial_m3110_con_setup(struct console *co, char *options) | ||
215 | { | ||
216 | struct uart_max3110 *max = pmax; | ||
217 | int baud = 115200; | ||
218 | int bits = 8; | ||
219 | int parity = 'n'; | ||
220 | int flow = 'n'; | ||
221 | |||
222 | pr_info(PR_FMT "setting up console\n"); | ||
223 | |||
224 | if (co->index == -1) | ||
225 | co->index = 0; | ||
226 | |||
227 | if (!max) { | ||
228 | pr_err(PR_FMT "pmax is NULL, return"); | ||
229 | return -ENODEV; | ||
230 | } | ||
231 | |||
232 | if (options) | ||
233 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
234 | |||
235 | return uart_set_options(&max->port, co, baud, parity, bits, flow); | ||
236 | } | ||
237 | |||
238 | static struct tty_driver *serial_m3110_con_device(struct console *co, | ||
239 | int *index) | ||
240 | { | ||
241 | struct uart_driver *p = co->data; | ||
242 | *index = co->index; | ||
243 | return p->tty_driver; | ||
244 | } | ||
245 | |||
246 | static struct uart_driver serial_m3110_reg; | ||
247 | static struct console serial_m3110_console = { | ||
248 | .name = "ttyS", | ||
249 | .write = serial_m3110_con_write, | ||
250 | .device = serial_m3110_con_device, | ||
251 | .setup = serial_m3110_con_setup, | ||
252 | .flags = CON_PRINTBUFFER, | ||
253 | .index = -1, | ||
254 | .data = &serial_m3110_reg, | ||
255 | }; | ||
256 | |||
257 | static unsigned int serial_m3110_tx_empty(struct uart_port *port) | ||
258 | { | ||
259 | return 1; | ||
260 | } | ||
261 | |||
262 | static void serial_m3110_stop_tx(struct uart_port *port) | ||
263 | { | ||
264 | return; | ||
265 | } | ||
266 | |||
267 | /* stop_rx will be called in spin_lock env */ | ||
268 | static void serial_m3110_stop_rx(struct uart_port *port) | ||
269 | { | ||
270 | return; | ||
271 | } | ||
272 | |||
273 | #define WORDS_PER_XFER 128 | ||
274 | static void send_circ_buf(struct uart_max3110 *max, | ||
275 | struct circ_buf *xmit) | ||
276 | { | ||
277 | void *buf; | ||
278 | u16 *obuf, *ibuf; | ||
279 | u8 valid_str[WORDS_PER_XFER]; | ||
280 | int i, j, len, blen, dma_size, left, ret = 0; | ||
281 | |||
282 | |||
283 | dma_size = WORDS_PER_XFER * sizeof(u16) * 2; | ||
284 | buf = kzalloc(dma_size, GFP_KERNEL | GFP_DMA); | ||
285 | if (!buf) | ||
286 | return; | ||
287 | obuf = buf; | ||
288 | ibuf = buf + dma_size/2; | ||
289 | |||
290 | while (!uart_circ_empty(xmit)) { | ||
291 | left = uart_circ_chars_pending(xmit); | ||
292 | while (left) { | ||
293 | len = min(left, WORDS_PER_XFER); | ||
294 | blen = len * sizeof(u16); | ||
295 | memset(ibuf, 0, blen); | ||
296 | |||
297 | for (i = 0; i < len; i++) { | ||
298 | obuf[i] = (u8)xmit->buf[xmit->tail] | WD_TAG; | ||
299 | xmit->tail = (xmit->tail + 1) & | ||
300 | (UART_XMIT_SIZE - 1); | ||
301 | } | ||
302 | |||
303 | /* Fail to send msg to console is not very critical */ | ||
304 | ret = max3110_write_then_read(max, obuf, ibuf, blen, 0); | ||
305 | if (ret) | ||
306 | pr_warning(PR_FMT "%s(): get err msg %d\n", | ||
307 | __func__, ret); | ||
308 | |||
309 | for (i = 0, j = 0; i < len; i++) { | ||
310 | if (ibuf[i] & MAX3110_READ_DATA_AVAILABLE) | ||
311 | valid_str[j++] = ibuf[i] & 0xff; | ||
312 | } | ||
313 | |||
314 | if (j) | ||
315 | receive_chars(max, valid_str, j); | ||
316 | |||
317 | max->port.icount.tx += len; | ||
318 | left -= len; | ||
319 | } | ||
320 | } | ||
321 | |||
322 | kfree(buf); | ||
323 | } | ||
324 | |||
325 | static void transmit_char(struct uart_max3110 *max) | ||
326 | { | ||
327 | struct uart_port *port = &max->port; | ||
328 | struct circ_buf *xmit = &port->state->xmit; | ||
329 | |||
330 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) | ||
331 | return; | ||
332 | |||
333 | send_circ_buf(max, xmit); | ||
334 | |||
335 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
336 | uart_write_wakeup(port); | ||
337 | |||
338 | if (uart_circ_empty(xmit)) | ||
339 | serial_m3110_stop_tx(port); | ||
340 | } | ||
341 | |||
342 | /* | ||
343 | * This will be called by uart_write() and tty_write, can't | ||
344 | * go to sleep | ||
345 | */ | ||
346 | static void serial_m3110_start_tx(struct uart_port *port) | ||
347 | { | ||
348 | struct uart_max3110 *max = | ||
349 | container_of(port, struct uart_max3110, port); | ||
350 | |||
351 | if (!test_and_set_bit(UART_TX_NEEDED, &max->uart_flags)) | ||
352 | wake_up_process(max->main_thread); | ||
353 | } | ||
354 | |||
355 | static void receive_chars(struct uart_max3110 *max, unsigned char *str, int len) | ||
356 | { | ||
357 | struct uart_port *port = &max->port; | ||
358 | struct tty_struct *tty; | ||
359 | int usable; | ||
360 | |||
361 | /* If uart is not opened, just return */ | ||
362 | if (!port->state) | ||
363 | return; | ||
364 | |||
365 | tty = port->state->port.tty; | ||
366 | if (!tty) | ||
367 | return; | ||
368 | |||
369 | while (len) { | ||
370 | usable = tty_buffer_request_room(tty, len); | ||
371 | if (usable) { | ||
372 | tty_insert_flip_string(tty, str, usable); | ||
373 | str += usable; | ||
374 | port->icount.rx += usable; | ||
375 | } | ||
376 | len -= usable; | ||
377 | } | ||
378 | tty_flip_buffer_push(tty); | ||
379 | } | ||
380 | |||
381 | /* | ||
382 | * This routine will be used in read_thread or RX IRQ handling, | ||
383 | * it will first do one round buffer read(8 words), if there is some | ||
384 | * valid RX data, will try to read 5 more rounds till all data | ||
385 | * is read out. | ||
386 | * | ||
387 | * Use stack space as data buffer to save some system load, and chose | ||
388 | * 504 Btyes as a threadhold to do a bulk push to upper tty layer when | ||
389 | * receiving bulk data, a much bigger buffer may cause stack overflow | ||
390 | */ | ||
391 | static void max3110_con_receive(struct uart_max3110 *max) | ||
392 | { | ||
393 | int loop = 1, num, total = 0; | ||
394 | u8 recv_buf[512], *pbuf; | ||
395 | |||
396 | pbuf = recv_buf; | ||
397 | do { | ||
398 | num = max3110_read_multi(max, pbuf); | ||
399 | |||
400 | if (num) { | ||
401 | loop = 5; | ||
402 | pbuf += num; | ||
403 | total += num; | ||
404 | |||
405 | if (total >= 504) { | ||
406 | receive_chars(max, recv_buf, total); | ||
407 | pbuf = recv_buf; | ||
408 | total = 0; | ||
409 | } | ||
410 | } | ||
411 | } while (--loop); | ||
412 | |||
413 | if (total) | ||
414 | receive_chars(max, recv_buf, total); | ||
415 | } | ||
416 | |||
417 | static int max3110_main_thread(void *_max) | ||
418 | { | ||
419 | struct uart_max3110 *max = _max; | ||
420 | wait_queue_head_t *wq = &max->wq; | ||
421 | int ret = 0; | ||
422 | struct circ_buf *xmit = &max->con_xmit; | ||
423 | |||
424 | init_waitqueue_head(wq); | ||
425 | pr_info(PR_FMT "start main thread\n"); | ||
426 | |||
427 | do { | ||
428 | wait_event_interruptible(*wq, max->uart_flags || kthread_should_stop()); | ||
429 | |||
430 | mutex_lock(&max->thread_mutex); | ||
431 | |||
432 | if (test_and_clear_bit(BIT_IRQ_PENDING, &max->uart_flags)) | ||
433 | max3110_con_receive(max); | ||
434 | |||
435 | /* first handle console output */ | ||
436 | if (test_and_clear_bit(CON_TX_NEEDED, &max->uart_flags)) | ||
437 | send_circ_buf(max, xmit); | ||
438 | |||
439 | /* handle uart output */ | ||
440 | if (test_and_clear_bit(UART_TX_NEEDED, &max->uart_flags)) | ||
441 | transmit_char(max); | ||
442 | |||
443 | mutex_unlock(&max->thread_mutex); | ||
444 | |||
445 | } while (!kthread_should_stop()); | ||
446 | |||
447 | return ret; | ||
448 | } | ||
449 | |||
450 | static irqreturn_t serial_m3110_irq(int irq, void *dev_id) | ||
451 | { | ||
452 | struct uart_max3110 *max = dev_id; | ||
453 | |||
454 | /* max3110's irq is a falling edge, not level triggered, | ||
455 | * so no need to disable the irq */ | ||
456 | if (!test_and_set_bit(BIT_IRQ_PENDING, &max->uart_flags)) | ||
457 | wake_up_process(max->main_thread); | ||
458 | |||
459 | return IRQ_HANDLED; | ||
460 | } | ||
461 | |||
462 | /* if don't use RX IRQ, then need a thread to polling read */ | ||
463 | static int max3110_read_thread(void *_max) | ||
464 | { | ||
465 | struct uart_max3110 *max = _max; | ||
466 | |||
467 | pr_info(PR_FMT "start read thread\n"); | ||
468 | do { | ||
469 | /* | ||
470 | * If can't acquire the mutex, it means the main thread | ||
471 | * is running which will also perform the rx job | ||
472 | */ | ||
473 | if (mutex_trylock(&max->thread_mutex)) { | ||
474 | max3110_con_receive(max); | ||
475 | mutex_unlock(&max->thread_mutex); | ||
476 | } | ||
477 | |||
478 | set_current_state(TASK_INTERRUPTIBLE); | ||
479 | schedule_timeout(HZ / 20); | ||
480 | } while (!kthread_should_stop()); | ||
481 | |||
482 | return 0; | ||
483 | } | ||
484 | |||
485 | static int serial_m3110_startup(struct uart_port *port) | ||
486 | { | ||
487 | struct uart_max3110 *max = | ||
488 | container_of(port, struct uart_max3110, port); | ||
489 | u16 config = 0; | ||
490 | int ret = 0; | ||
491 | |||
492 | if (port->line != 0) { | ||
493 | pr_err(PR_FMT "uart port startup failed\n"); | ||
494 | return -1; | ||
495 | } | ||
496 | |||
497 | /* Disable all IRQ and config it to 115200, 8n1 */ | ||
498 | config = WC_TAG | WC_FIFO_ENABLE | ||
499 | | WC_1_STOPBITS | ||
500 | | WC_8BIT_WORD | ||
501 | | WC_BAUD_DR2; | ||
502 | |||
503 | /* as we use thread to handle tx/rx, need set low latency */ | ||
504 | port->state->port.tty->low_latency = 1; | ||
505 | |||
506 | if (max->irq) { | ||
507 | max->read_thread = NULL; | ||
508 | ret = request_irq(max->irq, serial_m3110_irq, | ||
509 | IRQ_TYPE_EDGE_FALLING, "max3110", max); | ||
510 | if (ret) { | ||
511 | max->irq = 0; | ||
512 | pr_err(PR_FMT "unable to allocate IRQ, polling\n"); | ||
513 | } else { | ||
514 | /* Enable RX IRQ only */ | ||
515 | config |= WC_RXA_IRQ_ENABLE; | ||
516 | } | ||
517 | } | ||
518 | |||
519 | if (max->irq == 0) { | ||
520 | /* If IRQ is disabled, start a read thread for input data */ | ||
521 | max->read_thread = | ||
522 | kthread_run(max3110_read_thread, max, "max3110_read"); | ||
523 | if (IS_ERR(max->read_thread)) { | ||
524 | ret = PTR_ERR(max->read_thread); | ||
525 | max->read_thread = NULL; | ||
526 | pr_err(PR_FMT "Can't create read thread!\n"); | ||
527 | return ret; | ||
528 | } | ||
529 | } | ||
530 | |||
531 | ret = max3110_out(max, config); | ||
532 | if (ret) { | ||
533 | if (max->irq) | ||
534 | free_irq(max->irq, max); | ||
535 | if (max->read_thread) | ||
536 | kthread_stop(max->read_thread); | ||
537 | max->read_thread = NULL; | ||
538 | return ret; | ||
539 | } | ||
540 | |||
541 | max->cur_conf = config; | ||
542 | return 0; | ||
543 | } | ||
544 | |||
545 | static void serial_m3110_shutdown(struct uart_port *port) | ||
546 | { | ||
547 | struct uart_max3110 *max = | ||
548 | container_of(port, struct uart_max3110, port); | ||
549 | u16 config; | ||
550 | |||
551 | if (max->read_thread) { | ||
552 | kthread_stop(max->read_thread); | ||
553 | max->read_thread = NULL; | ||
554 | } | ||
555 | |||
556 | if (max->irq) | ||
557 | free_irq(max->irq, max); | ||
558 | |||
559 | /* Disable interrupts from this port */ | ||
560 | config = WC_TAG | WC_SW_SHDI; | ||
561 | max3110_out(max, config); | ||
562 | } | ||
563 | |||
564 | static void serial_m3110_release_port(struct uart_port *port) | ||
565 | { | ||
566 | } | ||
567 | |||
568 | static int serial_m3110_request_port(struct uart_port *port) | ||
569 | { | ||
570 | return 0; | ||
571 | } | ||
572 | |||
573 | static void serial_m3110_config_port(struct uart_port *port, int flags) | ||
574 | { | ||
575 | port->type = PORT_MAX3100; | ||
576 | } | ||
577 | |||
578 | static int | ||
579 | serial_m3110_verify_port(struct uart_port *port, struct serial_struct *ser) | ||
580 | { | ||
581 | /* we don't want the core code to modify any port params */ | ||
582 | return -EINVAL; | ||
583 | } | ||
584 | |||
585 | |||
586 | static const char *serial_m3110_type(struct uart_port *port) | ||
587 | { | ||
588 | struct uart_max3110 *max = | ||
589 | container_of(port, struct uart_max3110, port); | ||
590 | return max->name; | ||
591 | } | ||
592 | |||
593 | static void | ||
594 | serial_m3110_set_termios(struct uart_port *port, struct ktermios *termios, | ||
595 | struct ktermios *old) | ||
596 | { | ||
597 | struct uart_max3110 *max = | ||
598 | container_of(port, struct uart_max3110, port); | ||
599 | unsigned char cval; | ||
600 | unsigned int baud, parity = 0; | ||
601 | int clk_div = -1; | ||
602 | u16 new_conf = max->cur_conf; | ||
603 | |||
604 | switch (termios->c_cflag & CSIZE) { | ||
605 | case CS7: | ||
606 | cval = UART_LCR_WLEN7; | ||
607 | new_conf |= WC_7BIT_WORD; | ||
608 | break; | ||
609 | default: | ||
610 | /* We only support CS7 & CS8 */ | ||
611 | termios->c_cflag &= ~CSIZE; | ||
612 | termios->c_cflag |= CS8; | ||
613 | case CS8: | ||
614 | cval = UART_LCR_WLEN8; | ||
615 | new_conf |= WC_8BIT_WORD; | ||
616 | break; | ||
617 | } | ||
618 | |||
619 | baud = uart_get_baud_rate(port, termios, old, 0, 230400); | ||
620 | |||
621 | /* First calc the div for 1.8MHZ clock case */ | ||
622 | switch (baud) { | ||
623 | case 300: | ||
624 | clk_div = WC_BAUD_DR384; | ||
625 | break; | ||
626 | case 600: | ||
627 | clk_div = WC_BAUD_DR192; | ||
628 | break; | ||
629 | case 1200: | ||
630 | clk_div = WC_BAUD_DR96; | ||
631 | break; | ||
632 | case 2400: | ||
633 | clk_div = WC_BAUD_DR48; | ||
634 | break; | ||
635 | case 4800: | ||
636 | clk_div = WC_BAUD_DR24; | ||
637 | break; | ||
638 | case 9600: | ||
639 | clk_div = WC_BAUD_DR12; | ||
640 | break; | ||
641 | case 19200: | ||
642 | clk_div = WC_BAUD_DR6; | ||
643 | break; | ||
644 | case 38400: | ||
645 | clk_div = WC_BAUD_DR3; | ||
646 | break; | ||
647 | case 57600: | ||
648 | clk_div = WC_BAUD_DR2; | ||
649 | break; | ||
650 | case 115200: | ||
651 | clk_div = WC_BAUD_DR1; | ||
652 | break; | ||
653 | case 230400: | ||
654 | if (max->clock & MAX3110_HIGH_CLK) | ||
655 | break; | ||
656 | default: | ||
657 | /* Pick the previous baud rate */ | ||
658 | baud = max->baud; | ||
659 | clk_div = max->cur_conf & WC_BAUD_DIV_MASK; | ||
660 | tty_termios_encode_baud_rate(termios, baud, baud); | ||
661 | } | ||
662 | |||
663 | if (max->clock & MAX3110_HIGH_CLK) { | ||
664 | clk_div += 1; | ||
665 | /* High clk version max3110 doesn't support B300 */ | ||
666 | if (baud == 300) { | ||
667 | baud = 600; | ||
668 | clk_div = WC_BAUD_DR384; | ||
669 | } | ||
670 | if (baud == 230400) | ||
671 | clk_div = WC_BAUD_DR1; | ||
672 | tty_termios_encode_baud_rate(termios, baud, baud); | ||
673 | } | ||
674 | |||
675 | new_conf = (new_conf & ~WC_BAUD_DIV_MASK) | clk_div; | ||
676 | |||
677 | if (unlikely(termios->c_cflag & CMSPAR)) | ||
678 | termios->c_cflag &= ~CMSPAR; | ||
679 | |||
680 | if (termios->c_cflag & CSTOPB) | ||
681 | new_conf |= WC_2_STOPBITS; | ||
682 | else | ||
683 | new_conf &= ~WC_2_STOPBITS; | ||
684 | |||
685 | if (termios->c_cflag & PARENB) { | ||
686 | new_conf |= WC_PARITY_ENABLE; | ||
687 | parity |= UART_LCR_PARITY; | ||
688 | } else | ||
689 | new_conf &= ~WC_PARITY_ENABLE; | ||
690 | |||
691 | if (!(termios->c_cflag & PARODD)) | ||
692 | parity |= UART_LCR_EPAR; | ||
693 | max->parity = parity; | ||
694 | |||
695 | uart_update_timeout(port, termios->c_cflag, baud); | ||
696 | |||
697 | new_conf |= WC_TAG; | ||
698 | if (new_conf != max->cur_conf) { | ||
699 | if (!max3110_out(max, new_conf)) { | ||
700 | max->cur_conf = new_conf; | ||
701 | max->baud = baud; | ||
702 | } | ||
703 | } | ||
704 | } | ||
705 | |||
706 | /* Don't handle hw handshaking */ | ||
707 | static unsigned int serial_m3110_get_mctrl(struct uart_port *port) | ||
708 | { | ||
709 | return TIOCM_DSR | TIOCM_CAR | TIOCM_DSR; | ||
710 | } | ||
711 | |||
712 | static void serial_m3110_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
713 | { | ||
714 | } | ||
715 | |||
716 | static void serial_m3110_break_ctl(struct uart_port *port, int break_state) | ||
717 | { | ||
718 | } | ||
719 | |||
720 | static void serial_m3110_pm(struct uart_port *port, unsigned int state, | ||
721 | unsigned int oldstate) | ||
722 | { | ||
723 | } | ||
724 | |||
725 | static void serial_m3110_enable_ms(struct uart_port *port) | ||
726 | { | ||
727 | } | ||
728 | |||
729 | struct uart_ops serial_m3110_ops = { | ||
730 | .tx_empty = serial_m3110_tx_empty, | ||
731 | .set_mctrl = serial_m3110_set_mctrl, | ||
732 | .get_mctrl = serial_m3110_get_mctrl, | ||
733 | .stop_tx = serial_m3110_stop_tx, | ||
734 | .start_tx = serial_m3110_start_tx, | ||
735 | .stop_rx = serial_m3110_stop_rx, | ||
736 | .enable_ms = serial_m3110_enable_ms, | ||
737 | .break_ctl = serial_m3110_break_ctl, | ||
738 | .startup = serial_m3110_startup, | ||
739 | .shutdown = serial_m3110_shutdown, | ||
740 | .set_termios = serial_m3110_set_termios, | ||
741 | .pm = serial_m3110_pm, | ||
742 | .type = serial_m3110_type, | ||
743 | .release_port = serial_m3110_release_port, | ||
744 | .request_port = serial_m3110_request_port, | ||
745 | .config_port = serial_m3110_config_port, | ||
746 | .verify_port = serial_m3110_verify_port, | ||
747 | }; | ||
748 | |||
749 | static struct uart_driver serial_m3110_reg = { | ||
750 | .owner = THIS_MODULE, | ||
751 | .driver_name = "MRST serial", | ||
752 | .dev_name = "ttyS", | ||
753 | .major = TTY_MAJOR, | ||
754 | .minor = 64, | ||
755 | .nr = 1, | ||
756 | .cons = &serial_m3110_console, | ||
757 | }; | ||
758 | |||
759 | #ifdef CONFIG_PM | ||
760 | static int serial_m3110_suspend(struct spi_device *spi, pm_message_t state) | ||
761 | { | ||
762 | struct uart_max3110 *max = spi_get_drvdata(spi); | ||
763 | |||
764 | disable_irq(max->irq); | ||
765 | uart_suspend_port(&serial_m3110_reg, &max->port); | ||
766 | max3110_out(max, max->cur_conf | WC_SW_SHDI); | ||
767 | return 0; | ||
768 | } | ||
769 | |||
770 | static int serial_m3110_resume(struct spi_device *spi) | ||
771 | { | ||
772 | struct uart_max3110 *max = spi_get_drvdata(spi); | ||
773 | |||
774 | max3110_out(max, max->cur_conf); | ||
775 | uart_resume_port(&serial_m3110_reg, &max->port); | ||
776 | enable_irq(max->irq); | ||
777 | return 0; | ||
778 | } | ||
779 | #else | ||
780 | #define serial_m3110_suspend NULL | ||
781 | #define serial_m3110_resume NULL | ||
782 | #endif | ||
783 | |||
784 | static int __devinit serial_m3110_probe(struct spi_device *spi) | ||
785 | { | ||
786 | struct uart_max3110 *max; | ||
787 | void *buffer; | ||
788 | u16 res; | ||
789 | int ret = 0; | ||
790 | |||
791 | max = kzalloc(sizeof(*max), GFP_KERNEL); | ||
792 | if (!max) | ||
793 | return -ENOMEM; | ||
794 | |||
795 | /* Set spi info */ | ||
796 | spi->bits_per_word = 16; | ||
797 | max->clock = MAX3110_HIGH_CLK; | ||
798 | |||
799 | spi_setup(spi); | ||
800 | |||
801 | max->port.type = PORT_MAX3100; | ||
802 | max->port.fifosize = 2; /* Only have 16b buffer */ | ||
803 | max->port.ops = &serial_m3110_ops; | ||
804 | max->port.line = 0; | ||
805 | max->port.dev = &spi->dev; | ||
806 | max->port.uartclk = 115200; | ||
807 | |||
808 | max->spi = spi; | ||
809 | strcpy(max->name, spi->modalias); | ||
810 | max->irq = (u16)spi->irq; | ||
811 | |||
812 | mutex_init(&max->thread_mutex); | ||
813 | |||
814 | max->word_7bits = 0; | ||
815 | max->parity = 0; | ||
816 | max->baud = 0; | ||
817 | |||
818 | max->cur_conf = 0; | ||
819 | max->uart_flags = 0; | ||
820 | |||
821 | /* Check if reading configuration register returns something sane */ | ||
822 | |||
823 | res = RC_TAG; | ||
824 | ret = max3110_write_then_read(max, (u8 *)&res, (u8 *)&res, 2, 0); | ||
825 | if (ret < 0 || res == 0 || res == 0xffff) { | ||
826 | printk(KERN_ERR "MAX3111 deemed not present (conf reg %04x)", | ||
827 | res); | ||
828 | ret = -ENODEV; | ||
829 | goto err_get_page; | ||
830 | } | ||
831 | |||
832 | buffer = (void *)__get_free_page(GFP_KERNEL); | ||
833 | if (!buffer) { | ||
834 | ret = -ENOMEM; | ||
835 | goto err_get_page; | ||
836 | } | ||
837 | max->con_xmit.buf = buffer; | ||
838 | max->con_xmit.head = 0; | ||
839 | max->con_xmit.tail = 0; | ||
840 | |||
841 | max->main_thread = kthread_run(max3110_main_thread, | ||
842 | max, "max3110_main"); | ||
843 | if (IS_ERR(max->main_thread)) { | ||
844 | ret = PTR_ERR(max->main_thread); | ||
845 | goto err_kthread; | ||
846 | } | ||
847 | |||
848 | spi_set_drvdata(spi, max); | ||
849 | pmax = max; | ||
850 | |||
851 | /* Give membase a psudo value to pass serial_core's check */ | ||
852 | max->port.membase = (void *)0xff110000; | ||
853 | uart_add_one_port(&serial_m3110_reg, &max->port); | ||
854 | |||
855 | return 0; | ||
856 | |||
857 | err_kthread: | ||
858 | free_page((unsigned long)buffer); | ||
859 | err_get_page: | ||
860 | kfree(max); | ||
861 | return ret; | ||
862 | } | ||
863 | |||
864 | static int __devexit serial_m3110_remove(struct spi_device *dev) | ||
865 | { | ||
866 | struct uart_max3110 *max = spi_get_drvdata(dev); | ||
867 | |||
868 | if (!max) | ||
869 | return 0; | ||
870 | |||
871 | uart_remove_one_port(&serial_m3110_reg, &max->port); | ||
872 | |||
873 | free_page((unsigned long)max->con_xmit.buf); | ||
874 | |||
875 | if (max->main_thread) | ||
876 | kthread_stop(max->main_thread); | ||
877 | |||
878 | kfree(max); | ||
879 | return 0; | ||
880 | } | ||
881 | |||
882 | static struct spi_driver uart_max3110_driver = { | ||
883 | .driver = { | ||
884 | .name = "spi_max3111", | ||
885 | .bus = &spi_bus_type, | ||
886 | .owner = THIS_MODULE, | ||
887 | }, | ||
888 | .probe = serial_m3110_probe, | ||
889 | .remove = __devexit_p(serial_m3110_remove), | ||
890 | .suspend = serial_m3110_suspend, | ||
891 | .resume = serial_m3110_resume, | ||
892 | }; | ||
893 | |||
894 | static int __init serial_m3110_init(void) | ||
895 | { | ||
896 | int ret = 0; | ||
897 | |||
898 | ret = uart_register_driver(&serial_m3110_reg); | ||
899 | if (ret) | ||
900 | return ret; | ||
901 | |||
902 | ret = spi_register_driver(&uart_max3110_driver); | ||
903 | if (ret) | ||
904 | uart_unregister_driver(&serial_m3110_reg); | ||
905 | |||
906 | return ret; | ||
907 | } | ||
908 | |||
909 | static void __exit serial_m3110_exit(void) | ||
910 | { | ||
911 | spi_unregister_driver(&uart_max3110_driver); | ||
912 | uart_unregister_driver(&serial_m3110_reg); | ||
913 | } | ||
914 | |||
915 | module_init(serial_m3110_init); | ||
916 | module_exit(serial_m3110_exit); | ||
917 | |||
918 | MODULE_LICENSE("GPL v2"); | ||
919 | MODULE_ALIAS("max3110-uart"); | ||
diff --git a/drivers/serial/mrst_max3110.h b/drivers/serial/mrst_max3110.h new file mode 100644 index 000000000000..d1ef43af397c --- /dev/null +++ b/drivers/serial/mrst_max3110.h | |||
@@ -0,0 +1,60 @@ | |||
1 | #ifndef _MRST_MAX3110_H | ||
2 | #define _MRST_MAX3110_H | ||
3 | |||
4 | #define MAX3110_HIGH_CLK 0x1 /* 3.6864 MHZ */ | ||
5 | #define MAX3110_LOW_CLK 0x0 /* 1.8432 MHZ */ | ||
6 | |||
7 | /* status bits for all 4 MAX3110 operate modes */ | ||
8 | #define MAX3110_READ_DATA_AVAILABLE (1 << 15) | ||
9 | #define MAX3110_WRITE_BUF_EMPTY (1 << 14) | ||
10 | |||
11 | #define WC_TAG (3 << 14) | ||
12 | #define RC_TAG (1 << 14) | ||
13 | #define WD_TAG (2 << 14) | ||
14 | #define RD_TAG (0 << 14) | ||
15 | |||
16 | /* bits def for write configuration */ | ||
17 | #define WC_FIFO_ENABLE_MASK (1 << 13) | ||
18 | #define WC_FIFO_ENABLE (0 << 13) | ||
19 | |||
20 | #define WC_SW_SHDI (1 << 12) | ||
21 | |||
22 | #define WC_IRQ_MASK (0xF << 8) | ||
23 | #define WC_TXE_IRQ_ENABLE (1 << 11) /* TX empty irq */ | ||
24 | #define WC_RXA_IRQ_ENABLE (1 << 10) /* RX availabe irq */ | ||
25 | #define WC_PAR_HIGH_IRQ_ENABLE (1 << 9) | ||
26 | #define WC_REC_ACT_IRQ_ENABLE (1 << 8) | ||
27 | |||
28 | #define WC_IRDA_ENABLE (1 << 7) | ||
29 | |||
30 | #define WC_STOPBITS_MASK (1 << 6) | ||
31 | #define WC_2_STOPBITS (1 << 6) | ||
32 | #define WC_1_STOPBITS (0 << 6) | ||
33 | |||
34 | #define WC_PARITY_ENABLE_MASK (1 << 5) | ||
35 | #define WC_PARITY_ENABLE (1 << 5) | ||
36 | |||
37 | #define WC_WORDLEN_MASK (1 << 4) | ||
38 | #define WC_7BIT_WORD (1 << 4) | ||
39 | #define WC_8BIT_WORD (0 << 4) | ||
40 | |||
41 | #define WC_BAUD_DIV_MASK (0xF) | ||
42 | #define WC_BAUD_DR1 (0x0) | ||
43 | #define WC_BAUD_DR2 (0x1) | ||
44 | #define WC_BAUD_DR4 (0x2) | ||
45 | #define WC_BAUD_DR8 (0x3) | ||
46 | #define WC_BAUD_DR16 (0x4) | ||
47 | #define WC_BAUD_DR32 (0x5) | ||
48 | #define WC_BAUD_DR64 (0x6) | ||
49 | #define WC_BAUD_DR128 (0x7) | ||
50 | #define WC_BAUD_DR3 (0x8) | ||
51 | #define WC_BAUD_DR6 (0x9) | ||
52 | #define WC_BAUD_DR12 (0xA) | ||
53 | #define WC_BAUD_DR24 (0xB) | ||
54 | #define WC_BAUD_DR48 (0xC) | ||
55 | #define WC_BAUD_DR96 (0xD) | ||
56 | #define WC_BAUD_DR192 (0xE) | ||
57 | #define WC_BAUD_DR384 (0xF) | ||
58 | |||
59 | #define M3110_RX_FIFO_DEPTH 8 | ||
60 | #endif | ||
diff --git a/drivers/serial/msm_serial.c b/drivers/serial/msm_serial.c index 698048f64f5e..8e43a7b69e64 100644 --- a/drivers/serial/msm_serial.c +++ b/drivers/serial/msm_serial.c | |||
@@ -41,19 +41,6 @@ struct msm_port { | |||
41 | unsigned int imr; | 41 | unsigned int imr; |
42 | }; | 42 | }; |
43 | 43 | ||
44 | #define UART_TO_MSM(uart_port) ((struct msm_port *) uart_port) | ||
45 | |||
46 | static inline void msm_write(struct uart_port *port, unsigned int val, | ||
47 | unsigned int off) | ||
48 | { | ||
49 | __raw_writel(val, port->membase + off); | ||
50 | } | ||
51 | |||
52 | static inline unsigned int msm_read(struct uart_port *port, unsigned int off) | ||
53 | { | ||
54 | return __raw_readl(port->membase + off); | ||
55 | } | ||
56 | |||
57 | static void msm_stop_tx(struct uart_port *port) | 44 | static void msm_stop_tx(struct uart_port *port) |
58 | { | 45 | { |
59 | struct msm_port *msm_port = UART_TO_MSM(port); | 46 | struct msm_port *msm_port = UART_TO_MSM(port); |
@@ -88,7 +75,7 @@ static void msm_enable_ms(struct uart_port *port) | |||
88 | 75 | ||
89 | static void handle_rx(struct uart_port *port) | 76 | static void handle_rx(struct uart_port *port) |
90 | { | 77 | { |
91 | struct tty_struct *tty = port->info->port.tty; | 78 | struct tty_struct *tty = port->state->port.tty; |
92 | unsigned int sr; | 79 | unsigned int sr; |
93 | 80 | ||
94 | /* | 81 | /* |
@@ -136,7 +123,7 @@ static void handle_rx(struct uart_port *port) | |||
136 | 123 | ||
137 | static void handle_tx(struct uart_port *port) | 124 | static void handle_tx(struct uart_port *port) |
138 | { | 125 | { |
139 | struct circ_buf *xmit = &port->info->xmit; | 126 | struct circ_buf *xmit = &port->state->xmit; |
140 | struct msm_port *msm_port = UART_TO_MSM(port); | 127 | struct msm_port *msm_port = UART_TO_MSM(port); |
141 | int sent_tx; | 128 | int sent_tx; |
142 | 129 | ||
@@ -169,7 +156,7 @@ static void handle_delta_cts(struct uart_port *port) | |||
169 | { | 156 | { |
170 | msm_write(port, UART_CR_CMD_RESET_CTS, UART_CR); | 157 | msm_write(port, UART_CR_CMD_RESET_CTS, UART_CR); |
171 | port->icount.cts++; | 158 | port->icount.cts++; |
172 | wake_up_interruptible(&port->info->delta_msr_wait); | 159 | wake_up_interruptible(&port->state->port.delta_msr_wait); |
173 | } | 160 | } |
174 | 161 | ||
175 | static irqreturn_t msm_irq(int irq, void *dev_id) | 162 | static irqreturn_t msm_irq(int irq, void *dev_id) |
@@ -320,11 +307,7 @@ static void msm_init_clock(struct uart_port *port) | |||
320 | struct msm_port *msm_port = UART_TO_MSM(port); | 307 | struct msm_port *msm_port = UART_TO_MSM(port); |
321 | 308 | ||
322 | clk_enable(msm_port->clk); | 309 | clk_enable(msm_port->clk); |
323 | 310 | msm_serial_set_mnd_regs(port); | |
324 | msm_write(port, 0xC0, UART_MREG); | ||
325 | msm_write(port, 0xB2, UART_NREG); | ||
326 | msm_write(port, 0x7D, UART_DREG); | ||
327 | msm_write(port, 0x1C, UART_MNDREG); | ||
328 | } | 311 | } |
329 | 312 | ||
330 | static int msm_startup(struct uart_port *port) | 313 | static int msm_startup(struct uart_port *port) |
@@ -691,6 +674,7 @@ static int __init msm_serial_probe(struct platform_device *pdev) | |||
691 | struct msm_port *msm_port; | 674 | struct msm_port *msm_port; |
692 | struct resource *resource; | 675 | struct resource *resource; |
693 | struct uart_port *port; | 676 | struct uart_port *port; |
677 | int irq; | ||
694 | 678 | ||
695 | if (unlikely(pdev->id < 0 || pdev->id >= UART_NR)) | 679 | if (unlikely(pdev->id < 0 || pdev->id >= UART_NR)) |
696 | return -ENXIO; | 680 | return -ENXIO; |
@@ -702,18 +686,21 @@ static int __init msm_serial_probe(struct platform_device *pdev) | |||
702 | msm_port = UART_TO_MSM(port); | 686 | msm_port = UART_TO_MSM(port); |
703 | 687 | ||
704 | msm_port->clk = clk_get(&pdev->dev, "uart_clk"); | 688 | msm_port->clk = clk_get(&pdev->dev, "uart_clk"); |
705 | if (unlikely(IS_ERR(msm_port->clk))) | 689 | if (IS_ERR(msm_port->clk)) |
706 | return PTR_ERR(msm_port->clk); | 690 | return PTR_ERR(msm_port->clk); |
707 | port->uartclk = clk_get_rate(msm_port->clk); | 691 | port->uartclk = clk_get_rate(msm_port->clk); |
692 | printk(KERN_INFO "uartclk = %d\n", port->uartclk); | ||
693 | |||
708 | 694 | ||
709 | resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 695 | resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
710 | if (unlikely(!resource)) | 696 | if (unlikely(!resource)) |
711 | return -ENXIO; | 697 | return -ENXIO; |
712 | port->mapbase = resource->start; | 698 | port->mapbase = resource->start; |
713 | 699 | ||
714 | port->irq = platform_get_irq(pdev, 0); | 700 | irq = platform_get_irq(pdev, 0); |
715 | if (unlikely(port->irq < 0)) | 701 | if (unlikely(irq < 0)) |
716 | return -ENXIO; | 702 | return -ENXIO; |
703 | port->irq = irq; | ||
717 | 704 | ||
718 | platform_set_drvdata(pdev, port); | 705 | platform_set_drvdata(pdev, port); |
719 | 706 | ||
@@ -730,7 +717,6 @@ static int __devexit msm_serial_remove(struct platform_device *pdev) | |||
730 | } | 717 | } |
731 | 718 | ||
732 | static struct platform_driver msm_platform_driver = { | 719 | static struct platform_driver msm_platform_driver = { |
733 | .probe = msm_serial_probe, | ||
734 | .remove = msm_serial_remove, | 720 | .remove = msm_serial_remove, |
735 | .driver = { | 721 | .driver = { |
736 | .name = "msm_serial", | 722 | .name = "msm_serial", |
diff --git a/drivers/serial/msm_serial.h b/drivers/serial/msm_serial.h index 689f1fa0e84e..f6ca9ca79e98 100644 --- a/drivers/serial/msm_serial.h +++ b/drivers/serial/msm_serial.h | |||
@@ -114,4 +114,60 @@ | |||
114 | #define UART_MISR 0x0010 | 114 | #define UART_MISR 0x0010 |
115 | #define UART_ISR 0x0014 | 115 | #define UART_ISR 0x0014 |
116 | 116 | ||
117 | #define UART_TO_MSM(uart_port) ((struct msm_port *) uart_port) | ||
118 | |||
119 | static inline | ||
120 | void msm_write(struct uart_port *port, unsigned int val, unsigned int off) | ||
121 | { | ||
122 | __raw_writel(val, port->membase + off); | ||
123 | } | ||
124 | |||
125 | static inline | ||
126 | unsigned int msm_read(struct uart_port *port, unsigned int off) | ||
127 | { | ||
128 | return __raw_readl(port->membase + off); | ||
129 | } | ||
130 | |||
131 | /* | ||
132 | * Setup the MND registers to use the TCXO clock. | ||
133 | */ | ||
134 | static inline void msm_serial_set_mnd_regs_tcxo(struct uart_port *port) | ||
135 | { | ||
136 | msm_write(port, 0x06, UART_MREG); | ||
137 | msm_write(port, 0xF1, UART_NREG); | ||
138 | msm_write(port, 0x0F, UART_DREG); | ||
139 | msm_write(port, 0x1A, UART_MNDREG); | ||
140 | } | ||
141 | |||
142 | /* | ||
143 | * Setup the MND registers to use the TCXO clock divided by 4. | ||
144 | */ | ||
145 | static inline void msm_serial_set_mnd_regs_tcxoby4(struct uart_port *port) | ||
146 | { | ||
147 | msm_write(port, 0x18, UART_MREG); | ||
148 | msm_write(port, 0xF6, UART_NREG); | ||
149 | msm_write(port, 0x0F, UART_DREG); | ||
150 | msm_write(port, 0x0A, UART_MNDREG); | ||
151 | } | ||
152 | |||
153 | static inline | ||
154 | void msm_serial_set_mnd_regs_from_uartclk(struct uart_port *port) | ||
155 | { | ||
156 | if (port->uartclk == 19200000) | ||
157 | msm_serial_set_mnd_regs_tcxo(port); | ||
158 | else | ||
159 | msm_serial_set_mnd_regs_tcxoby4(port); | ||
160 | } | ||
161 | |||
162 | /* | ||
163 | * TROUT has a specific defect that makes it report it's uartclk | ||
164 | * as 19.2Mhz (TCXO) when it's actually 4.8Mhz (TCXO/4). This special | ||
165 | * cases TROUT to use the right clock. | ||
166 | */ | ||
167 | #ifdef CONFIG_MACH_TROUT | ||
168 | #define msm_serial_set_mnd_regs msm_serial_set_mnd_regs_tcxoby4 | ||
169 | #else | ||
170 | #define msm_serial_set_mnd_regs msm_serial_set_mnd_regs_from_uartclk | ||
171 | #endif | ||
172 | |||
117 | #endif /* __DRIVERS_SERIAL_MSM_SERIAL_H */ | 173 | #endif /* __DRIVERS_SERIAL_MSM_SERIAL_H */ |
diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c index 953a5ffa9b44..9711e06a8374 100644 --- a/drivers/serial/mux.c +++ b/drivers/serial/mux.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/serial.h> | 23 | #include <linux/serial.h> |
24 | #include <linux/console.h> | 24 | #include <linux/console.h> |
25 | #include <linux/slab.h> | ||
26 | #include <linux/delay.h> /* for udelay */ | 25 | #include <linux/delay.h> /* for udelay */ |
27 | #include <linux/device.h> | 26 | #include <linux/device.h> |
28 | #include <asm/io.h> | 27 | #include <asm/io.h> |
@@ -199,7 +198,7 @@ static void mux_break_ctl(struct uart_port *port, int break_state) | |||
199 | static void mux_write(struct uart_port *port) | 198 | static void mux_write(struct uart_port *port) |
200 | { | 199 | { |
201 | int count; | 200 | int count; |
202 | struct circ_buf *xmit = &port->info->xmit; | 201 | struct circ_buf *xmit = &port->state->xmit; |
203 | 202 | ||
204 | if(port->x_char) { | 203 | if(port->x_char) { |
205 | UART_PUT_CHAR(port, port->x_char); | 204 | UART_PUT_CHAR(port, port->x_char); |
@@ -243,7 +242,7 @@ static void mux_write(struct uart_port *port) | |||
243 | static void mux_read(struct uart_port *port) | 242 | static void mux_read(struct uart_port *port) |
244 | { | 243 | { |
245 | int data; | 244 | int data; |
246 | struct tty_struct *tty = port->info->port.tty; | 245 | struct tty_struct *tty = port->state->port.tty; |
247 | __u32 start_count = port->icount.rx; | 246 | __u32 start_count = port->icount.rx; |
248 | 247 | ||
249 | while(1) { | 248 | while(1) { |
diff --git a/drivers/serial/netx-serial.c b/drivers/serial/netx-serial.c index 3e5dda8518b7..7735c9f35fa0 100644 --- a/drivers/serial/netx-serial.c +++ b/drivers/serial/netx-serial.c | |||
@@ -140,7 +140,7 @@ static void netx_enable_ms(struct uart_port *port) | |||
140 | 140 | ||
141 | static inline void netx_transmit_buffer(struct uart_port *port) | 141 | static inline void netx_transmit_buffer(struct uart_port *port) |
142 | { | 142 | { |
143 | struct circ_buf *xmit = &port->info->xmit; | 143 | struct circ_buf *xmit = &port->state->xmit; |
144 | 144 | ||
145 | if (port->x_char) { | 145 | if (port->x_char) { |
146 | writel(port->x_char, port->membase + UART_DR); | 146 | writel(port->x_char, port->membase + UART_DR); |
@@ -185,7 +185,7 @@ static unsigned int netx_tx_empty(struct uart_port *port) | |||
185 | 185 | ||
186 | static void netx_txint(struct uart_port *port) | 186 | static void netx_txint(struct uart_port *port) |
187 | { | 187 | { |
188 | struct circ_buf *xmit = &port->info->xmit; | 188 | struct circ_buf *xmit = &port->state->xmit; |
189 | 189 | ||
190 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { | 190 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { |
191 | netx_stop_tx(port); | 191 | netx_stop_tx(port); |
@@ -201,7 +201,7 @@ static void netx_txint(struct uart_port *port) | |||
201 | static void netx_rxint(struct uart_port *port) | 201 | static void netx_rxint(struct uart_port *port) |
202 | { | 202 | { |
203 | unsigned char rx, flg, status; | 203 | unsigned char rx, flg, status; |
204 | struct tty_struct *tty = port->info->port.tty; | 204 | struct tty_struct *tty = port->state->port.tty; |
205 | 205 | ||
206 | while (!(readl(port->membase + UART_FR) & FR_RXFE)) { | 206 | while (!(readl(port->membase + UART_FR) & FR_RXFE)) { |
207 | rx = readl(port->membase + UART_DR); | 207 | rx = readl(port->membase + UART_DR); |
diff --git a/drivers/serial/nwpserial.c b/drivers/serial/nwpserial.c index 9e150b19d726..de173671e3d0 100644 --- a/drivers/serial/nwpserial.c +++ b/drivers/serial/nwpserial.c | |||
@@ -81,7 +81,7 @@ nwpserial_console_write(struct console *co, const char *s, unsigned int count) | |||
81 | 81 | ||
82 | uart_console_write(&up->port, s, count, nwpserial_console_putchar); | 82 | uart_console_write(&up->port, s, count, nwpserial_console_putchar); |
83 | 83 | ||
84 | /* wait for transmitter to become emtpy */ | 84 | /* wait for transmitter to become empty */ |
85 | while ((dcr_read(up->dcr_host, UART_LSR) & UART_LSR_THRE) == 0) | 85 | while ((dcr_read(up->dcr_host, UART_LSR) & UART_LSR_THRE) == 0) |
86 | cpu_relax(); | 86 | cpu_relax(); |
87 | 87 | ||
@@ -126,7 +126,7 @@ static void nwpserial_config_port(struct uart_port *port, int flags) | |||
126 | static irqreturn_t nwpserial_interrupt(int irq, void *dev_id) | 126 | static irqreturn_t nwpserial_interrupt(int irq, void *dev_id) |
127 | { | 127 | { |
128 | struct nwpserial_port *up = dev_id; | 128 | struct nwpserial_port *up = dev_id; |
129 | struct tty_struct *tty = up->port.info->port.tty; | 129 | struct tty_struct *tty = up->port.state->port.tty; |
130 | irqreturn_t ret; | 130 | irqreturn_t ret; |
131 | unsigned int iir; | 131 | unsigned int iir; |
132 | unsigned char ch; | 132 | unsigned char ch; |
@@ -261,7 +261,7 @@ static void nwpserial_start_tx(struct uart_port *port) | |||
261 | struct nwpserial_port *up; | 261 | struct nwpserial_port *up; |
262 | struct circ_buf *xmit; | 262 | struct circ_buf *xmit; |
263 | up = container_of(port, struct nwpserial_port, port); | 263 | up = container_of(port, struct nwpserial_port, port); |
264 | xmit = &up->port.info->xmit; | 264 | xmit = &up->port.state->xmit; |
265 | 265 | ||
266 | if (port->x_char) { | 266 | if (port->x_char) { |
267 | nwpserial_putchar(up, up->port.x_char); | 267 | nwpserial_putchar(up, up->port.x_char); |
@@ -344,7 +344,7 @@ int nwpserial_register_port(struct uart_port *port) | |||
344 | 344 | ||
345 | mutex_lock(&nwpserial_mutex); | 345 | mutex_lock(&nwpserial_mutex); |
346 | 346 | ||
347 | dn = to_of_device(port->dev)->node; | 347 | dn = port->dev->of_node; |
348 | if (dn == NULL) | 348 | if (dn == NULL) |
349 | goto out; | 349 | goto out; |
350 | 350 | ||
diff --git a/drivers/serial/of_serial.c b/drivers/serial/of_serial.c index 02406ba6da1c..5c7abe4c94dd 100644 --- a/drivers/serial/of_serial.c +++ b/drivers/serial/of_serial.c | |||
@@ -11,13 +11,14 @@ | |||
11 | */ | 11 | */ |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/slab.h> | ||
14 | #include <linux/serial_core.h> | 15 | #include <linux/serial_core.h> |
15 | #include <linux/serial_8250.h> | 16 | #include <linux/serial_8250.h> |
17 | #include <linux/of_address.h> | ||
18 | #include <linux/of_irq.h> | ||
16 | #include <linux/of_platform.h> | 19 | #include <linux/of_platform.h> |
17 | #include <linux/nwpserial.h> | 20 | #include <linux/nwpserial.h> |
18 | 21 | ||
19 | #include <asm/prom.h> | ||
20 | |||
21 | struct of_serial_info { | 22 | struct of_serial_info { |
22 | int type; | 23 | int type; |
23 | int line; | 24 | int line; |
@@ -26,13 +27,13 @@ struct of_serial_info { | |||
26 | /* | 27 | /* |
27 | * Fill a struct uart_port for a given device node | 28 | * Fill a struct uart_port for a given device node |
28 | */ | 29 | */ |
29 | static int __devinit of_platform_serial_setup(struct of_device *ofdev, | 30 | static int __devinit of_platform_serial_setup(struct platform_device *ofdev, |
30 | int type, struct uart_port *port) | 31 | int type, struct uart_port *port) |
31 | { | 32 | { |
32 | struct resource resource; | 33 | struct resource resource; |
33 | struct device_node *np = ofdev->node; | 34 | struct device_node *np = ofdev->dev.of_node; |
34 | const unsigned int *clk, *spd; | 35 | const __be32 *clk, *spd; |
35 | const u32 *prop; | 36 | const __be32 *prop; |
36 | int ret, prop_size; | 37 | int ret, prop_size; |
37 | 38 | ||
38 | memset(port, 0, sizeof *port); | 39 | memset(port, 0, sizeof *port); |
@@ -55,23 +56,23 @@ static int __devinit of_platform_serial_setup(struct of_device *ofdev, | |||
55 | /* Check for shifted address mapping */ | 56 | /* Check for shifted address mapping */ |
56 | prop = of_get_property(np, "reg-offset", &prop_size); | 57 | prop = of_get_property(np, "reg-offset", &prop_size); |
57 | if (prop && (prop_size == sizeof(u32))) | 58 | if (prop && (prop_size == sizeof(u32))) |
58 | port->mapbase += *prop; | 59 | port->mapbase += be32_to_cpup(prop); |
59 | 60 | ||
60 | /* Check for registers offset within the devices address range */ | 61 | /* Check for registers offset within the devices address range */ |
61 | prop = of_get_property(np, "reg-shift", &prop_size); | 62 | prop = of_get_property(np, "reg-shift", &prop_size); |
62 | if (prop && (prop_size == sizeof(u32))) | 63 | if (prop && (prop_size == sizeof(u32))) |
63 | port->regshift = *prop; | 64 | port->regshift = be32_to_cpup(prop); |
64 | 65 | ||
65 | port->irq = irq_of_parse_and_map(np, 0); | 66 | port->irq = irq_of_parse_and_map(np, 0); |
66 | port->iotype = UPIO_MEM; | 67 | port->iotype = UPIO_MEM; |
67 | port->type = type; | 68 | port->type = type; |
68 | port->uartclk = *clk; | 69 | port->uartclk = be32_to_cpup(clk); |
69 | port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP | 70 | port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP |
70 | | UPF_FIXED_PORT | UPF_FIXED_TYPE; | 71 | | UPF_FIXED_PORT | UPF_FIXED_TYPE; |
71 | port->dev = &ofdev->dev; | 72 | port->dev = &ofdev->dev; |
72 | /* If current-speed was set, then try not to change it. */ | 73 | /* If current-speed was set, then try not to change it. */ |
73 | if (spd) | 74 | if (spd) |
74 | port->custom_divisor = *clk / (16 * (*spd)); | 75 | port->custom_divisor = be32_to_cpup(clk) / (16 * (be32_to_cpup(spd))); |
75 | 76 | ||
76 | return 0; | 77 | return 0; |
77 | } | 78 | } |
@@ -79,7 +80,7 @@ static int __devinit of_platform_serial_setup(struct of_device *ofdev, | |||
79 | /* | 80 | /* |
80 | * Try to register a serial port | 81 | * Try to register a serial port |
81 | */ | 82 | */ |
82 | static int __devinit of_platform_serial_probe(struct of_device *ofdev, | 83 | static int __devinit of_platform_serial_probe(struct platform_device *ofdev, |
83 | const struct of_device_id *id) | 84 | const struct of_device_id *id) |
84 | { | 85 | { |
85 | struct of_serial_info *info; | 86 | struct of_serial_info *info; |
@@ -87,7 +88,7 @@ static int __devinit of_platform_serial_probe(struct of_device *ofdev, | |||
87 | int port_type; | 88 | int port_type; |
88 | int ret; | 89 | int ret; |
89 | 90 | ||
90 | if (of_find_property(ofdev->node, "used-by-rtas", NULL)) | 91 | if (of_find_property(ofdev->dev.of_node, "used-by-rtas", NULL)) |
91 | return -EBUSY; | 92 | return -EBUSY; |
92 | 93 | ||
93 | info = kmalloc(sizeof(*info), GFP_KERNEL); | 94 | info = kmalloc(sizeof(*info), GFP_KERNEL); |
@@ -133,7 +134,7 @@ out: | |||
133 | /* | 134 | /* |
134 | * Release a line | 135 | * Release a line |
135 | */ | 136 | */ |
136 | static int of_platform_serial_remove(struct of_device *ofdev) | 137 | static int of_platform_serial_remove(struct platform_device *ofdev) |
137 | { | 138 | { |
138 | struct of_serial_info *info = dev_get_drvdata(&ofdev->dev); | 139 | struct of_serial_info *info = dev_get_drvdata(&ofdev->dev); |
139 | switch (info->type) { | 140 | switch (info->type) { |
@@ -161,6 +162,7 @@ static int of_platform_serial_remove(struct of_device *ofdev) | |||
161 | static struct of_device_id __devinitdata of_platform_serial_table[] = { | 162 | static struct of_device_id __devinitdata of_platform_serial_table[] = { |
162 | { .type = "serial", .compatible = "ns8250", .data = (void *)PORT_8250, }, | 163 | { .type = "serial", .compatible = "ns8250", .data = (void *)PORT_8250, }, |
163 | { .type = "serial", .compatible = "ns16450", .data = (void *)PORT_16450, }, | 164 | { .type = "serial", .compatible = "ns16450", .data = (void *)PORT_16450, }, |
165 | { .type = "serial", .compatible = "ns16550a", .data = (void *)PORT_16550A, }, | ||
164 | { .type = "serial", .compatible = "ns16550", .data = (void *)PORT_16550, }, | 166 | { .type = "serial", .compatible = "ns16550", .data = (void *)PORT_16550, }, |
165 | { .type = "serial", .compatible = "ns16750", .data = (void *)PORT_16750, }, | 167 | { .type = "serial", .compatible = "ns16750", .data = (void *)PORT_16750, }, |
166 | { .type = "serial", .compatible = "ns16850", .data = (void *)PORT_16850, }, | 168 | { .type = "serial", .compatible = "ns16850", .data = (void *)PORT_16850, }, |
@@ -173,11 +175,13 @@ static struct of_device_id __devinitdata of_platform_serial_table[] = { | |||
173 | }; | 175 | }; |
174 | 176 | ||
175 | static struct of_platform_driver of_platform_serial_driver = { | 177 | static struct of_platform_driver of_platform_serial_driver = { |
176 | .owner = THIS_MODULE, | 178 | .driver = { |
177 | .name = "of_serial", | 179 | .name = "of_serial", |
180 | .owner = THIS_MODULE, | ||
181 | .of_match_table = of_platform_serial_table, | ||
182 | }, | ||
178 | .probe = of_platform_serial_probe, | 183 | .probe = of_platform_serial_probe, |
179 | .remove = of_platform_serial_remove, | 184 | .remove = of_platform_serial_remove, |
180 | .match_table = of_platform_serial_table, | ||
181 | }; | 185 | }; |
182 | 186 | ||
183 | static int __init of_platform_serial_init(void) | 187 | static int __init of_platform_serial_init(void) |
diff --git a/drivers/serial/omap-serial.c b/drivers/serial/omap-serial.c new file mode 100644 index 000000000000..7f2f01058789 --- /dev/null +++ b/drivers/serial/omap-serial.c | |||
@@ -0,0 +1,1359 @@ | |||
1 | /* | ||
2 | * Driver for OMAP-UART controller. | ||
3 | * Based on drivers/serial/8250.c | ||
4 | * | ||
5 | * Copyright (C) 2010 Texas Instruments. | ||
6 | * | ||
7 | * Authors: | ||
8 | * Govindraj R <govindraj.raja@ti.com> | ||
9 | * Thara Gopinath <thara@ti.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * Note: This driver is made seperate from 8250 driver as we cannot | ||
17 | * over load 8250 driver with omap platform specific configuration for | ||
18 | * features like DMA, it makes easier to implement features like DMA and | ||
19 | * hardware flow control and software flow control configuration with | ||
20 | * this driver as required for the omap-platform. | ||
21 | */ | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/console.h> | ||
26 | #include <linux/serial_reg.h> | ||
27 | #include <linux/delay.h> | ||
28 | #include <linux/slab.h> | ||
29 | #include <linux/tty.h> | ||
30 | #include <linux/tty_flip.h> | ||
31 | #include <linux/io.h> | ||
32 | #include <linux/dma-mapping.h> | ||
33 | #include <linux/clk.h> | ||
34 | #include <linux/serial_core.h> | ||
35 | #include <linux/irq.h> | ||
36 | |||
37 | #include <plat/dma.h> | ||
38 | #include <plat/dmtimer.h> | ||
39 | #include <plat/omap-serial.h> | ||
40 | |||
41 | static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS]; | ||
42 | |||
43 | /* Forward declaration of functions */ | ||
44 | static void uart_tx_dma_callback(int lch, u16 ch_status, void *data); | ||
45 | static void serial_omap_rx_timeout(unsigned long uart_no); | ||
46 | static int serial_omap_start_rxdma(struct uart_omap_port *up); | ||
47 | |||
48 | static inline unsigned int serial_in(struct uart_omap_port *up, int offset) | ||
49 | { | ||
50 | offset <<= up->port.regshift; | ||
51 | return readw(up->port.membase + offset); | ||
52 | } | ||
53 | |||
54 | static inline void serial_out(struct uart_omap_port *up, int offset, int value) | ||
55 | { | ||
56 | offset <<= up->port.regshift; | ||
57 | writew(value, up->port.membase + offset); | ||
58 | } | ||
59 | |||
60 | static inline void serial_omap_clear_fifos(struct uart_omap_port *up) | ||
61 | { | ||
62 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); | ||
63 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | | ||
64 | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); | ||
65 | serial_out(up, UART_FCR, 0); | ||
66 | } | ||
67 | |||
68 | /* | ||
69 | * serial_omap_get_divisor - calculate divisor value | ||
70 | * @port: uart port info | ||
71 | * @baud: baudrate for which divisor needs to be calculated. | ||
72 | * | ||
73 | * We have written our own function to get the divisor so as to support | ||
74 | * 13x mode. 3Mbps Baudrate as an different divisor. | ||
75 | * Reference OMAP TRM Chapter 17: | ||
76 | * Table 17-1. UART Mode Baud Rates, Divisor Values, and Error Rates | ||
77 | * referring to oversampling - divisor value | ||
78 | * baudrate 460,800 to 3,686,400 all have divisor 13 | ||
79 | * except 3,000,000 which has divisor value 16 | ||
80 | */ | ||
81 | static unsigned int | ||
82 | serial_omap_get_divisor(struct uart_port *port, unsigned int baud) | ||
83 | { | ||
84 | unsigned int divisor; | ||
85 | |||
86 | if (baud > OMAP_MODE13X_SPEED && baud != 3000000) | ||
87 | divisor = 13; | ||
88 | else | ||
89 | divisor = 16; | ||
90 | return port->uartclk/(baud * divisor); | ||
91 | } | ||
92 | |||
93 | static void serial_omap_stop_rxdma(struct uart_omap_port *up) | ||
94 | { | ||
95 | if (up->uart_dma.rx_dma_used) { | ||
96 | del_timer(&up->uart_dma.rx_timer); | ||
97 | omap_stop_dma(up->uart_dma.rx_dma_channel); | ||
98 | omap_free_dma(up->uart_dma.rx_dma_channel); | ||
99 | up->uart_dma.rx_dma_channel = OMAP_UART_DMA_CH_FREE; | ||
100 | up->uart_dma.rx_dma_used = false; | ||
101 | } | ||
102 | } | ||
103 | |||
104 | static void serial_omap_enable_ms(struct uart_port *port) | ||
105 | { | ||
106 | struct uart_omap_port *up = (struct uart_omap_port *)port; | ||
107 | |||
108 | dev_dbg(up->port.dev, "serial_omap_enable_ms+%d\n", up->pdev->id); | ||
109 | up->ier |= UART_IER_MSI; | ||
110 | serial_out(up, UART_IER, up->ier); | ||
111 | } | ||
112 | |||
113 | static void serial_omap_stop_tx(struct uart_port *port) | ||
114 | { | ||
115 | struct uart_omap_port *up = (struct uart_omap_port *)port; | ||
116 | |||
117 | if (up->use_dma && | ||
118 | up->uart_dma.tx_dma_channel != OMAP_UART_DMA_CH_FREE) { | ||
119 | /* | ||
120 | * Check if dma is still active. If yes do nothing, | ||
121 | * return. Else stop dma | ||
122 | */ | ||
123 | if (omap_get_dma_active_status(up->uart_dma.tx_dma_channel)) | ||
124 | return; | ||
125 | omap_stop_dma(up->uart_dma.tx_dma_channel); | ||
126 | omap_free_dma(up->uart_dma.tx_dma_channel); | ||
127 | up->uart_dma.tx_dma_channel = OMAP_UART_DMA_CH_FREE; | ||
128 | } | ||
129 | |||
130 | if (up->ier & UART_IER_THRI) { | ||
131 | up->ier &= ~UART_IER_THRI; | ||
132 | serial_out(up, UART_IER, up->ier); | ||
133 | } | ||
134 | } | ||
135 | |||
136 | static void serial_omap_stop_rx(struct uart_port *port) | ||
137 | { | ||
138 | struct uart_omap_port *up = (struct uart_omap_port *)port; | ||
139 | |||
140 | if (up->use_dma) | ||
141 | serial_omap_stop_rxdma(up); | ||
142 | up->ier &= ~UART_IER_RLSI; | ||
143 | up->port.read_status_mask &= ~UART_LSR_DR; | ||
144 | serial_out(up, UART_IER, up->ier); | ||
145 | } | ||
146 | |||
147 | static inline void receive_chars(struct uart_omap_port *up, int *status) | ||
148 | { | ||
149 | struct tty_struct *tty = up->port.state->port.tty; | ||
150 | unsigned int flag; | ||
151 | unsigned char ch, lsr = *status; | ||
152 | int max_count = 256; | ||
153 | |||
154 | do { | ||
155 | if (likely(lsr & UART_LSR_DR)) | ||
156 | ch = serial_in(up, UART_RX); | ||
157 | flag = TTY_NORMAL; | ||
158 | up->port.icount.rx++; | ||
159 | |||
160 | if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) { | ||
161 | /* | ||
162 | * For statistics only | ||
163 | */ | ||
164 | if (lsr & UART_LSR_BI) { | ||
165 | lsr &= ~(UART_LSR_FE | UART_LSR_PE); | ||
166 | up->port.icount.brk++; | ||
167 | /* | ||
168 | * We do the SysRQ and SAK checking | ||
169 | * here because otherwise the break | ||
170 | * may get masked by ignore_status_mask | ||
171 | * or read_status_mask. | ||
172 | */ | ||
173 | if (uart_handle_break(&up->port)) | ||
174 | goto ignore_char; | ||
175 | } else if (lsr & UART_LSR_PE) { | ||
176 | up->port.icount.parity++; | ||
177 | } else if (lsr & UART_LSR_FE) { | ||
178 | up->port.icount.frame++; | ||
179 | } | ||
180 | |||
181 | if (lsr & UART_LSR_OE) | ||
182 | up->port.icount.overrun++; | ||
183 | |||
184 | /* | ||
185 | * Mask off conditions which should be ignored. | ||
186 | */ | ||
187 | lsr &= up->port.read_status_mask; | ||
188 | |||
189 | #ifdef CONFIG_SERIAL_OMAP_CONSOLE | ||
190 | if (up->port.line == up->port.cons->index) { | ||
191 | /* Recover the break flag from console xmit */ | ||
192 | lsr |= up->lsr_break_flag; | ||
193 | up->lsr_break_flag = 0; | ||
194 | } | ||
195 | #endif | ||
196 | if (lsr & UART_LSR_BI) | ||
197 | flag = TTY_BREAK; | ||
198 | else if (lsr & UART_LSR_PE) | ||
199 | flag = TTY_PARITY; | ||
200 | else if (lsr & UART_LSR_FE) | ||
201 | flag = TTY_FRAME; | ||
202 | } | ||
203 | |||
204 | if (uart_handle_sysrq_char(&up->port, ch)) | ||
205 | goto ignore_char; | ||
206 | uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, flag); | ||
207 | ignore_char: | ||
208 | lsr = serial_in(up, UART_LSR); | ||
209 | } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0)); | ||
210 | spin_unlock(&up->port.lock); | ||
211 | tty_flip_buffer_push(tty); | ||
212 | spin_lock(&up->port.lock); | ||
213 | } | ||
214 | |||
215 | static void transmit_chars(struct uart_omap_port *up) | ||
216 | { | ||
217 | struct circ_buf *xmit = &up->port.state->xmit; | ||
218 | int count; | ||
219 | |||
220 | if (up->port.x_char) { | ||
221 | serial_out(up, UART_TX, up->port.x_char); | ||
222 | up->port.icount.tx++; | ||
223 | up->port.x_char = 0; | ||
224 | return; | ||
225 | } | ||
226 | if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { | ||
227 | serial_omap_stop_tx(&up->port); | ||
228 | return; | ||
229 | } | ||
230 | count = up->port.fifosize / 4; | ||
231 | do { | ||
232 | serial_out(up, UART_TX, xmit->buf[xmit->tail]); | ||
233 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
234 | up->port.icount.tx++; | ||
235 | if (uart_circ_empty(xmit)) | ||
236 | break; | ||
237 | } while (--count > 0); | ||
238 | |||
239 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
240 | uart_write_wakeup(&up->port); | ||
241 | |||
242 | if (uart_circ_empty(xmit)) | ||
243 | serial_omap_stop_tx(&up->port); | ||
244 | } | ||
245 | |||
246 | static inline void serial_omap_enable_ier_thri(struct uart_omap_port *up) | ||
247 | { | ||
248 | if (!(up->ier & UART_IER_THRI)) { | ||
249 | up->ier |= UART_IER_THRI; | ||
250 | serial_out(up, UART_IER, up->ier); | ||
251 | } | ||
252 | } | ||
253 | |||
254 | static void serial_omap_start_tx(struct uart_port *port) | ||
255 | { | ||
256 | struct uart_omap_port *up = (struct uart_omap_port *)port; | ||
257 | struct circ_buf *xmit; | ||
258 | unsigned int start; | ||
259 | int ret = 0; | ||
260 | |||
261 | if (!up->use_dma) { | ||
262 | serial_omap_enable_ier_thri(up); | ||
263 | return; | ||
264 | } | ||
265 | |||
266 | if (up->uart_dma.tx_dma_used) | ||
267 | return; | ||
268 | |||
269 | xmit = &up->port.state->xmit; | ||
270 | |||
271 | if (up->uart_dma.tx_dma_channel == OMAP_UART_DMA_CH_FREE) { | ||
272 | ret = omap_request_dma(up->uart_dma.uart_dma_tx, | ||
273 | "UART Tx DMA", | ||
274 | (void *)uart_tx_dma_callback, up, | ||
275 | &(up->uart_dma.tx_dma_channel)); | ||
276 | |||
277 | if (ret < 0) { | ||
278 | serial_omap_enable_ier_thri(up); | ||
279 | return; | ||
280 | } | ||
281 | } | ||
282 | spin_lock(&(up->uart_dma.tx_lock)); | ||
283 | up->uart_dma.tx_dma_used = true; | ||
284 | spin_unlock(&(up->uart_dma.tx_lock)); | ||
285 | |||
286 | start = up->uart_dma.tx_buf_dma_phys + | ||
287 | (xmit->tail & (UART_XMIT_SIZE - 1)); | ||
288 | |||
289 | up->uart_dma.tx_buf_size = uart_circ_chars_pending(xmit); | ||
290 | /* | ||
291 | * It is a circular buffer. See if the buffer has wounded back. | ||
292 | * If yes it will have to be transferred in two separate dma | ||
293 | * transfers | ||
294 | */ | ||
295 | if (start + up->uart_dma.tx_buf_size >= | ||
296 | up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE) | ||
297 | up->uart_dma.tx_buf_size = | ||
298 | (up->uart_dma.tx_buf_dma_phys + | ||
299 | UART_XMIT_SIZE) - start; | ||
300 | |||
301 | omap_set_dma_dest_params(up->uart_dma.tx_dma_channel, 0, | ||
302 | OMAP_DMA_AMODE_CONSTANT, | ||
303 | up->uart_dma.uart_base, 0, 0); | ||
304 | omap_set_dma_src_params(up->uart_dma.tx_dma_channel, 0, | ||
305 | OMAP_DMA_AMODE_POST_INC, start, 0, 0); | ||
306 | omap_set_dma_transfer_params(up->uart_dma.tx_dma_channel, | ||
307 | OMAP_DMA_DATA_TYPE_S8, | ||
308 | up->uart_dma.tx_buf_size, 1, | ||
309 | OMAP_DMA_SYNC_ELEMENT, | ||
310 | up->uart_dma.uart_dma_tx, 0); | ||
311 | /* FIXME: Cache maintenance needed here? */ | ||
312 | omap_start_dma(up->uart_dma.tx_dma_channel); | ||
313 | } | ||
314 | |||
315 | static unsigned int check_modem_status(struct uart_omap_port *up) | ||
316 | { | ||
317 | unsigned int status; | ||
318 | |||
319 | status = serial_in(up, UART_MSR); | ||
320 | status |= up->msr_saved_flags; | ||
321 | up->msr_saved_flags = 0; | ||
322 | if ((status & UART_MSR_ANY_DELTA) == 0) | ||
323 | return status; | ||
324 | |||
325 | if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI && | ||
326 | up->port.state != NULL) { | ||
327 | if (status & UART_MSR_TERI) | ||
328 | up->port.icount.rng++; | ||
329 | if (status & UART_MSR_DDSR) | ||
330 | up->port.icount.dsr++; | ||
331 | if (status & UART_MSR_DDCD) | ||
332 | uart_handle_dcd_change | ||
333 | (&up->port, status & UART_MSR_DCD); | ||
334 | if (status & UART_MSR_DCTS) | ||
335 | uart_handle_cts_change | ||
336 | (&up->port, status & UART_MSR_CTS); | ||
337 | wake_up_interruptible(&up->port.state->port.delta_msr_wait); | ||
338 | } | ||
339 | |||
340 | return status; | ||
341 | } | ||
342 | |||
343 | /** | ||
344 | * serial_omap_irq() - This handles the interrupt from one port | ||
345 | * @irq: uart port irq number | ||
346 | * @dev_id: uart port info | ||
347 | */ | ||
348 | static inline irqreturn_t serial_omap_irq(int irq, void *dev_id) | ||
349 | { | ||
350 | struct uart_omap_port *up = dev_id; | ||
351 | unsigned int iir, lsr; | ||
352 | unsigned long flags; | ||
353 | |||
354 | iir = serial_in(up, UART_IIR); | ||
355 | if (iir & UART_IIR_NO_INT) | ||
356 | return IRQ_NONE; | ||
357 | |||
358 | spin_lock_irqsave(&up->port.lock, flags); | ||
359 | lsr = serial_in(up, UART_LSR); | ||
360 | if (iir & UART_IIR_RLSI) { | ||
361 | if (!up->use_dma) { | ||
362 | if (lsr & UART_LSR_DR) | ||
363 | receive_chars(up, &lsr); | ||
364 | } else { | ||
365 | up->ier &= ~(UART_IER_RDI | UART_IER_RLSI); | ||
366 | serial_out(up, UART_IER, up->ier); | ||
367 | if ((serial_omap_start_rxdma(up) != 0) && | ||
368 | (lsr & UART_LSR_DR)) | ||
369 | receive_chars(up, &lsr); | ||
370 | } | ||
371 | } | ||
372 | |||
373 | check_modem_status(up); | ||
374 | if ((lsr & UART_LSR_THRE) && (iir & UART_IIR_THRI)) | ||
375 | transmit_chars(up); | ||
376 | |||
377 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
378 | up->port_activity = jiffies; | ||
379 | return IRQ_HANDLED; | ||
380 | } | ||
381 | |||
382 | static unsigned int serial_omap_tx_empty(struct uart_port *port) | ||
383 | { | ||
384 | struct uart_omap_port *up = (struct uart_omap_port *)port; | ||
385 | unsigned long flags = 0; | ||
386 | unsigned int ret = 0; | ||
387 | |||
388 | dev_dbg(up->port.dev, "serial_omap_tx_empty+%d\n", up->pdev->id); | ||
389 | spin_lock_irqsave(&up->port.lock, flags); | ||
390 | ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; | ||
391 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
392 | |||
393 | return ret; | ||
394 | } | ||
395 | |||
396 | static unsigned int serial_omap_get_mctrl(struct uart_port *port) | ||
397 | { | ||
398 | struct uart_omap_port *up = (struct uart_omap_port *)port; | ||
399 | unsigned char status; | ||
400 | unsigned int ret = 0; | ||
401 | |||
402 | status = check_modem_status(up); | ||
403 | dev_dbg(up->port.dev, "serial_omap_get_mctrl+%d\n", up->pdev->id); | ||
404 | |||
405 | if (status & UART_MSR_DCD) | ||
406 | ret |= TIOCM_CAR; | ||
407 | if (status & UART_MSR_RI) | ||
408 | ret |= TIOCM_RNG; | ||
409 | if (status & UART_MSR_DSR) | ||
410 | ret |= TIOCM_DSR; | ||
411 | if (status & UART_MSR_CTS) | ||
412 | ret |= TIOCM_CTS; | ||
413 | return ret; | ||
414 | } | ||
415 | |||
416 | static void serial_omap_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
417 | { | ||
418 | struct uart_omap_port *up = (struct uart_omap_port *)port; | ||
419 | unsigned char mcr = 0; | ||
420 | |||
421 | dev_dbg(up->port.dev, "serial_omap_set_mctrl+%d\n", up->pdev->id); | ||
422 | if (mctrl & TIOCM_RTS) | ||
423 | mcr |= UART_MCR_RTS; | ||
424 | if (mctrl & TIOCM_DTR) | ||
425 | mcr |= UART_MCR_DTR; | ||
426 | if (mctrl & TIOCM_OUT1) | ||
427 | mcr |= UART_MCR_OUT1; | ||
428 | if (mctrl & TIOCM_OUT2) | ||
429 | mcr |= UART_MCR_OUT2; | ||
430 | if (mctrl & TIOCM_LOOP) | ||
431 | mcr |= UART_MCR_LOOP; | ||
432 | |||
433 | mcr |= up->mcr; | ||
434 | serial_out(up, UART_MCR, mcr); | ||
435 | } | ||
436 | |||
437 | static void serial_omap_break_ctl(struct uart_port *port, int break_state) | ||
438 | { | ||
439 | struct uart_omap_port *up = (struct uart_omap_port *)port; | ||
440 | unsigned long flags = 0; | ||
441 | |||
442 | dev_dbg(up->port.dev, "serial_omap_break_ctl+%d\n", up->pdev->id); | ||
443 | spin_lock_irqsave(&up->port.lock, flags); | ||
444 | if (break_state == -1) | ||
445 | up->lcr |= UART_LCR_SBC; | ||
446 | else | ||
447 | up->lcr &= ~UART_LCR_SBC; | ||
448 | serial_out(up, UART_LCR, up->lcr); | ||
449 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
450 | } | ||
451 | |||
452 | static int serial_omap_startup(struct uart_port *port) | ||
453 | { | ||
454 | struct uart_omap_port *up = (struct uart_omap_port *)port; | ||
455 | unsigned long flags = 0; | ||
456 | int retval; | ||
457 | |||
458 | /* | ||
459 | * Allocate the IRQ | ||
460 | */ | ||
461 | retval = request_irq(up->port.irq, serial_omap_irq, up->port.irqflags, | ||
462 | up->name, up); | ||
463 | if (retval) | ||
464 | return retval; | ||
465 | |||
466 | dev_dbg(up->port.dev, "serial_omap_startup+%d\n", up->pdev->id); | ||
467 | |||
468 | /* | ||
469 | * Clear the FIFO buffers and disable them. | ||
470 | * (they will be reenabled in set_termios()) | ||
471 | */ | ||
472 | serial_omap_clear_fifos(up); | ||
473 | /* For Hardware flow control */ | ||
474 | serial_out(up, UART_MCR, UART_MCR_RTS); | ||
475 | |||
476 | /* | ||
477 | * Clear the interrupt registers. | ||
478 | */ | ||
479 | (void) serial_in(up, UART_LSR); | ||
480 | if (serial_in(up, UART_LSR) & UART_LSR_DR) | ||
481 | (void) serial_in(up, UART_RX); | ||
482 | (void) serial_in(up, UART_IIR); | ||
483 | (void) serial_in(up, UART_MSR); | ||
484 | |||
485 | /* | ||
486 | * Now, initialize the UART | ||
487 | */ | ||
488 | serial_out(up, UART_LCR, UART_LCR_WLEN8); | ||
489 | spin_lock_irqsave(&up->port.lock, flags); | ||
490 | /* | ||
491 | * Most PC uarts need OUT2 raised to enable interrupts. | ||
492 | */ | ||
493 | up->port.mctrl |= TIOCM_OUT2; | ||
494 | serial_omap_set_mctrl(&up->port, up->port.mctrl); | ||
495 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
496 | |||
497 | up->msr_saved_flags = 0; | ||
498 | if (up->use_dma) { | ||
499 | free_page((unsigned long)up->port.state->xmit.buf); | ||
500 | up->port.state->xmit.buf = dma_alloc_coherent(NULL, | ||
501 | UART_XMIT_SIZE, | ||
502 | (dma_addr_t *)&(up->uart_dma.tx_buf_dma_phys), | ||
503 | 0); | ||
504 | init_timer(&(up->uart_dma.rx_timer)); | ||
505 | up->uart_dma.rx_timer.function = serial_omap_rx_timeout; | ||
506 | up->uart_dma.rx_timer.data = up->pdev->id; | ||
507 | /* Currently the buffer size is 4KB. Can increase it */ | ||
508 | up->uart_dma.rx_buf = dma_alloc_coherent(NULL, | ||
509 | up->uart_dma.rx_buf_size, | ||
510 | (dma_addr_t *)&(up->uart_dma.rx_buf_dma_phys), 0); | ||
511 | } | ||
512 | /* | ||
513 | * Finally, enable interrupts. Note: Modem status interrupts | ||
514 | * are set via set_termios(), which will be occurring imminently | ||
515 | * anyway, so we don't enable them here. | ||
516 | */ | ||
517 | up->ier = UART_IER_RLSI | UART_IER_RDI; | ||
518 | serial_out(up, UART_IER, up->ier); | ||
519 | |||
520 | up->port_activity = jiffies; | ||
521 | return 0; | ||
522 | } | ||
523 | |||
524 | static void serial_omap_shutdown(struct uart_port *port) | ||
525 | { | ||
526 | struct uart_omap_port *up = (struct uart_omap_port *)port; | ||
527 | unsigned long flags = 0; | ||
528 | |||
529 | dev_dbg(up->port.dev, "serial_omap_shutdown+%d\n", up->pdev->id); | ||
530 | /* | ||
531 | * Disable interrupts from this port | ||
532 | */ | ||
533 | up->ier = 0; | ||
534 | serial_out(up, UART_IER, 0); | ||
535 | |||
536 | spin_lock_irqsave(&up->port.lock, flags); | ||
537 | up->port.mctrl &= ~TIOCM_OUT2; | ||
538 | serial_omap_set_mctrl(&up->port, up->port.mctrl); | ||
539 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
540 | |||
541 | /* | ||
542 | * Disable break condition and FIFOs | ||
543 | */ | ||
544 | serial_out(up, UART_LCR, serial_in(up, UART_LCR) & ~UART_LCR_SBC); | ||
545 | serial_omap_clear_fifos(up); | ||
546 | |||
547 | /* | ||
548 | * Read data port to reset things, and then free the irq | ||
549 | */ | ||
550 | if (serial_in(up, UART_LSR) & UART_LSR_DR) | ||
551 | (void) serial_in(up, UART_RX); | ||
552 | if (up->use_dma) { | ||
553 | dma_free_coherent(up->port.dev, | ||
554 | UART_XMIT_SIZE, up->port.state->xmit.buf, | ||
555 | up->uart_dma.tx_buf_dma_phys); | ||
556 | up->port.state->xmit.buf = NULL; | ||
557 | serial_omap_stop_rx(port); | ||
558 | dma_free_coherent(up->port.dev, | ||
559 | up->uart_dma.rx_buf_size, up->uart_dma.rx_buf, | ||
560 | up->uart_dma.rx_buf_dma_phys); | ||
561 | up->uart_dma.rx_buf = NULL; | ||
562 | } | ||
563 | free_irq(up->port.irq, up); | ||
564 | } | ||
565 | |||
566 | static inline void | ||
567 | serial_omap_configure_xonxoff | ||
568 | (struct uart_omap_port *up, struct ktermios *termios) | ||
569 | { | ||
570 | unsigned char efr = 0; | ||
571 | |||
572 | up->lcr = serial_in(up, UART_LCR); | ||
573 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | ||
574 | up->efr = serial_in(up, UART_EFR); | ||
575 | serial_out(up, UART_EFR, up->efr & ~UART_EFR_ECB); | ||
576 | |||
577 | serial_out(up, UART_XON1, termios->c_cc[VSTART]); | ||
578 | serial_out(up, UART_XOFF1, termios->c_cc[VSTOP]); | ||
579 | |||
580 | /* clear SW control mode bits */ | ||
581 | efr = up->efr; | ||
582 | efr &= OMAP_UART_SW_CLR; | ||
583 | |||
584 | /* | ||
585 | * IXON Flag: | ||
586 | * Enable XON/XOFF flow control on output. | ||
587 | * Transmit XON1, XOFF1 | ||
588 | */ | ||
589 | if (termios->c_iflag & IXON) | ||
590 | efr |= OMAP_UART_SW_TX; | ||
591 | |||
592 | /* | ||
593 | * IXOFF Flag: | ||
594 | * Enable XON/XOFF flow control on input. | ||
595 | * Receiver compares XON1, XOFF1. | ||
596 | */ | ||
597 | if (termios->c_iflag & IXOFF) | ||
598 | efr |= OMAP_UART_SW_RX; | ||
599 | |||
600 | serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); | ||
601 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); | ||
602 | |||
603 | up->mcr = serial_in(up, UART_MCR); | ||
604 | |||
605 | /* | ||
606 | * IXANY Flag: | ||
607 | * Enable any character to restart output. | ||
608 | * Operation resumes after receiving any | ||
609 | * character after recognition of the XOFF character | ||
610 | */ | ||
611 | if (termios->c_iflag & IXANY) | ||
612 | up->mcr |= UART_MCR_XONANY; | ||
613 | |||
614 | serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); | ||
615 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | ||
616 | serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_TRIG); | ||
617 | /* Enable special char function UARTi.EFR_REG[5] and | ||
618 | * load the new software flow control mode IXON or IXOFF | ||
619 | * and restore the UARTi.EFR_REG[4] ENHANCED_EN value. | ||
620 | */ | ||
621 | serial_out(up, UART_EFR, efr | UART_EFR_SCD); | ||
622 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); | ||
623 | |||
624 | serial_out(up, UART_MCR, up->mcr & ~UART_MCR_TCRTLR); | ||
625 | serial_out(up, UART_LCR, up->lcr); | ||
626 | } | ||
627 | |||
628 | static void | ||
629 | serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, | ||
630 | struct ktermios *old) | ||
631 | { | ||
632 | struct uart_omap_port *up = (struct uart_omap_port *)port; | ||
633 | unsigned char cval = 0; | ||
634 | unsigned char efr = 0; | ||
635 | unsigned long flags = 0; | ||
636 | unsigned int baud, quot; | ||
637 | |||
638 | switch (termios->c_cflag & CSIZE) { | ||
639 | case CS5: | ||
640 | cval = UART_LCR_WLEN5; | ||
641 | break; | ||
642 | case CS6: | ||
643 | cval = UART_LCR_WLEN6; | ||
644 | break; | ||
645 | case CS7: | ||
646 | cval = UART_LCR_WLEN7; | ||
647 | break; | ||
648 | default: | ||
649 | case CS8: | ||
650 | cval = UART_LCR_WLEN8; | ||
651 | break; | ||
652 | } | ||
653 | |||
654 | if (termios->c_cflag & CSTOPB) | ||
655 | cval |= UART_LCR_STOP; | ||
656 | if (termios->c_cflag & PARENB) | ||
657 | cval |= UART_LCR_PARITY; | ||
658 | if (!(termios->c_cflag & PARODD)) | ||
659 | cval |= UART_LCR_EPAR; | ||
660 | |||
661 | /* | ||
662 | * Ask the core to calculate the divisor for us. | ||
663 | */ | ||
664 | |||
665 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/13); | ||
666 | quot = serial_omap_get_divisor(port, baud); | ||
667 | |||
668 | up->fcr = UART_FCR_R_TRIG_01 | UART_FCR_T_TRIG_01 | | ||
669 | UART_FCR_ENABLE_FIFO; | ||
670 | if (up->use_dma) | ||
671 | up->fcr |= UART_FCR_DMA_SELECT; | ||
672 | |||
673 | /* | ||
674 | * Ok, we're now changing the port state. Do it with | ||
675 | * interrupts disabled. | ||
676 | */ | ||
677 | spin_lock_irqsave(&up->port.lock, flags); | ||
678 | |||
679 | /* | ||
680 | * Update the per-port timeout. | ||
681 | */ | ||
682 | uart_update_timeout(port, termios->c_cflag, baud); | ||
683 | |||
684 | up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; | ||
685 | if (termios->c_iflag & INPCK) | ||
686 | up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE; | ||
687 | if (termios->c_iflag & (BRKINT | PARMRK)) | ||
688 | up->port.read_status_mask |= UART_LSR_BI; | ||
689 | |||
690 | /* | ||
691 | * Characters to ignore | ||
692 | */ | ||
693 | up->port.ignore_status_mask = 0; | ||
694 | if (termios->c_iflag & IGNPAR) | ||
695 | up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; | ||
696 | if (termios->c_iflag & IGNBRK) { | ||
697 | up->port.ignore_status_mask |= UART_LSR_BI; | ||
698 | /* | ||
699 | * If we're ignoring parity and break indicators, | ||
700 | * ignore overruns too (for real raw support). | ||
701 | */ | ||
702 | if (termios->c_iflag & IGNPAR) | ||
703 | up->port.ignore_status_mask |= UART_LSR_OE; | ||
704 | } | ||
705 | |||
706 | /* | ||
707 | * ignore all characters if CREAD is not set | ||
708 | */ | ||
709 | if ((termios->c_cflag & CREAD) == 0) | ||
710 | up->port.ignore_status_mask |= UART_LSR_DR; | ||
711 | |||
712 | /* | ||
713 | * Modem status interrupts | ||
714 | */ | ||
715 | up->ier &= ~UART_IER_MSI; | ||
716 | if (UART_ENABLE_MS(&up->port, termios->c_cflag)) | ||
717 | up->ier |= UART_IER_MSI; | ||
718 | serial_out(up, UART_IER, up->ier); | ||
719 | serial_out(up, UART_LCR, cval); /* reset DLAB */ | ||
720 | |||
721 | /* FIFOs and DMA Settings */ | ||
722 | |||
723 | /* FCR can be changed only when the | ||
724 | * baud clock is not running | ||
725 | * DLL_REG and DLH_REG set to 0. | ||
726 | */ | ||
727 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); | ||
728 | serial_out(up, UART_DLL, 0); | ||
729 | serial_out(up, UART_DLM, 0); | ||
730 | serial_out(up, UART_LCR, 0); | ||
731 | |||
732 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | ||
733 | |||
734 | up->efr = serial_in(up, UART_EFR); | ||
735 | serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); | ||
736 | |||
737 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); | ||
738 | up->mcr = serial_in(up, UART_MCR); | ||
739 | serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); | ||
740 | /* FIFO ENABLE, DMA MODE */ | ||
741 | serial_out(up, UART_FCR, up->fcr); | ||
742 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | ||
743 | |||
744 | if (up->use_dma) { | ||
745 | serial_out(up, UART_TI752_TLR, 0); | ||
746 | serial_out(up, UART_OMAP_SCR, | ||
747 | (UART_FCR_TRIGGER_4 | UART_FCR_TRIGGER_8)); | ||
748 | } | ||
749 | |||
750 | serial_out(up, UART_EFR, up->efr); | ||
751 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); | ||
752 | serial_out(up, UART_MCR, up->mcr); | ||
753 | |||
754 | /* Protocol, Baud Rate, and Interrupt Settings */ | ||
755 | |||
756 | serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE); | ||
757 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | ||
758 | |||
759 | up->efr = serial_in(up, UART_EFR); | ||
760 | serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); | ||
761 | |||
762 | serial_out(up, UART_LCR, 0); | ||
763 | serial_out(up, UART_IER, 0); | ||
764 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | ||
765 | |||
766 | serial_out(up, UART_DLL, quot & 0xff); /* LS of divisor */ | ||
767 | serial_out(up, UART_DLM, quot >> 8); /* MS of divisor */ | ||
768 | |||
769 | serial_out(up, UART_LCR, 0); | ||
770 | serial_out(up, UART_IER, up->ier); | ||
771 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | ||
772 | |||
773 | serial_out(up, UART_EFR, up->efr); | ||
774 | serial_out(up, UART_LCR, cval); | ||
775 | |||
776 | if (baud > 230400 && baud != 3000000) | ||
777 | serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_13X_MODE); | ||
778 | else | ||
779 | serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_16X_MODE); | ||
780 | |||
781 | /* Hardware Flow Control Configuration */ | ||
782 | |||
783 | if (termios->c_cflag & CRTSCTS) { | ||
784 | efr |= (UART_EFR_CTS | UART_EFR_RTS); | ||
785 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); | ||
786 | |||
787 | up->mcr = serial_in(up, UART_MCR); | ||
788 | serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); | ||
789 | |||
790 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | ||
791 | up->efr = serial_in(up, UART_EFR); | ||
792 | serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); | ||
793 | |||
794 | serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_TRIG); | ||
795 | serial_out(up, UART_EFR, efr); /* Enable AUTORTS and AUTOCTS */ | ||
796 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); | ||
797 | serial_out(up, UART_MCR, up->mcr | UART_MCR_RTS); | ||
798 | serial_out(up, UART_LCR, cval); | ||
799 | } | ||
800 | |||
801 | serial_omap_set_mctrl(&up->port, up->port.mctrl); | ||
802 | /* Software Flow Control Configuration */ | ||
803 | if (termios->c_iflag & (IXON | IXOFF)) | ||
804 | serial_omap_configure_xonxoff(up, termios); | ||
805 | |||
806 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
807 | dev_dbg(up->port.dev, "serial_omap_set_termios+%d\n", up->pdev->id); | ||
808 | } | ||
809 | |||
810 | static void | ||
811 | serial_omap_pm(struct uart_port *port, unsigned int state, | ||
812 | unsigned int oldstate) | ||
813 | { | ||
814 | struct uart_omap_port *up = (struct uart_omap_port *)port; | ||
815 | unsigned char efr; | ||
816 | |||
817 | dev_dbg(up->port.dev, "serial_omap_pm+%d\n", up->pdev->id); | ||
818 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | ||
819 | efr = serial_in(up, UART_EFR); | ||
820 | serial_out(up, UART_EFR, efr | UART_EFR_ECB); | ||
821 | serial_out(up, UART_LCR, 0); | ||
822 | |||
823 | serial_out(up, UART_IER, (state != 0) ? UART_IERX_SLEEP : 0); | ||
824 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | ||
825 | serial_out(up, UART_EFR, efr); | ||
826 | serial_out(up, UART_LCR, 0); | ||
827 | /* Enable module level wake up */ | ||
828 | serial_out(up, UART_OMAP_WER, | ||
829 | (state != 0) ? OMAP_UART_WER_MOD_WKUP : 0); | ||
830 | } | ||
831 | |||
832 | static void serial_omap_release_port(struct uart_port *port) | ||
833 | { | ||
834 | dev_dbg(port->dev, "serial_omap_release_port+\n"); | ||
835 | } | ||
836 | |||
837 | static int serial_omap_request_port(struct uart_port *port) | ||
838 | { | ||
839 | dev_dbg(port->dev, "serial_omap_request_port+\n"); | ||
840 | return 0; | ||
841 | } | ||
842 | |||
843 | static void serial_omap_config_port(struct uart_port *port, int flags) | ||
844 | { | ||
845 | struct uart_omap_port *up = (struct uart_omap_port *)port; | ||
846 | |||
847 | dev_dbg(up->port.dev, "serial_omap_config_port+%d\n", | ||
848 | up->pdev->id); | ||
849 | up->port.type = PORT_OMAP; | ||
850 | } | ||
851 | |||
852 | static int | ||
853 | serial_omap_verify_port(struct uart_port *port, struct serial_struct *ser) | ||
854 | { | ||
855 | /* we don't want the core code to modify any port params */ | ||
856 | dev_dbg(port->dev, "serial_omap_verify_port+\n"); | ||
857 | return -EINVAL; | ||
858 | } | ||
859 | |||
860 | static const char * | ||
861 | serial_omap_type(struct uart_port *port) | ||
862 | { | ||
863 | struct uart_omap_port *up = (struct uart_omap_port *)port; | ||
864 | |||
865 | dev_dbg(up->port.dev, "serial_omap_type+%d\n", up->pdev->id); | ||
866 | return up->name; | ||
867 | } | ||
868 | |||
869 | #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) | ||
870 | |||
871 | static inline void wait_for_xmitr(struct uart_omap_port *up) | ||
872 | { | ||
873 | unsigned int status, tmout = 10000; | ||
874 | |||
875 | /* Wait up to 10ms for the character(s) to be sent. */ | ||
876 | do { | ||
877 | status = serial_in(up, UART_LSR); | ||
878 | |||
879 | if (status & UART_LSR_BI) | ||
880 | up->lsr_break_flag = UART_LSR_BI; | ||
881 | |||
882 | if (--tmout == 0) | ||
883 | break; | ||
884 | udelay(1); | ||
885 | } while ((status & BOTH_EMPTY) != BOTH_EMPTY); | ||
886 | |||
887 | /* Wait up to 1s for flow control if necessary */ | ||
888 | if (up->port.flags & UPF_CONS_FLOW) { | ||
889 | tmout = 1000000; | ||
890 | for (tmout = 1000000; tmout; tmout--) { | ||
891 | unsigned int msr = serial_in(up, UART_MSR); | ||
892 | |||
893 | up->msr_saved_flags |= msr & MSR_SAVE_FLAGS; | ||
894 | if (msr & UART_MSR_CTS) | ||
895 | break; | ||
896 | |||
897 | udelay(1); | ||
898 | } | ||
899 | } | ||
900 | } | ||
901 | |||
902 | #ifdef CONFIG_CONSOLE_POLL | ||
903 | |||
904 | static void serial_omap_poll_put_char(struct uart_port *port, unsigned char ch) | ||
905 | { | ||
906 | struct uart_omap_port *up = (struct uart_omap_port *)port; | ||
907 | wait_for_xmitr(up); | ||
908 | serial_out(up, UART_TX, ch); | ||
909 | } | ||
910 | |||
911 | static int serial_omap_poll_get_char(struct uart_port *port) | ||
912 | { | ||
913 | struct uart_omap_port *up = (struct uart_omap_port *)port; | ||
914 | unsigned int status = serial_in(up, UART_LSR); | ||
915 | |||
916 | if (!(status & UART_LSR_DR)) | ||
917 | return NO_POLL_CHAR; | ||
918 | |||
919 | return serial_in(up, UART_RX); | ||
920 | } | ||
921 | |||
922 | #endif /* CONFIG_CONSOLE_POLL */ | ||
923 | |||
924 | #ifdef CONFIG_SERIAL_OMAP_CONSOLE | ||
925 | |||
926 | static struct uart_omap_port *serial_omap_console_ports[4]; | ||
927 | |||
928 | static struct uart_driver serial_omap_reg; | ||
929 | |||
930 | static void serial_omap_console_putchar(struct uart_port *port, int ch) | ||
931 | { | ||
932 | struct uart_omap_port *up = (struct uart_omap_port *)port; | ||
933 | |||
934 | wait_for_xmitr(up); | ||
935 | serial_out(up, UART_TX, ch); | ||
936 | } | ||
937 | |||
938 | static void | ||
939 | serial_omap_console_write(struct console *co, const char *s, | ||
940 | unsigned int count) | ||
941 | { | ||
942 | struct uart_omap_port *up = serial_omap_console_ports[co->index]; | ||
943 | unsigned long flags; | ||
944 | unsigned int ier; | ||
945 | int locked = 1; | ||
946 | |||
947 | local_irq_save(flags); | ||
948 | if (up->port.sysrq) | ||
949 | locked = 0; | ||
950 | else if (oops_in_progress) | ||
951 | locked = spin_trylock(&up->port.lock); | ||
952 | else | ||
953 | spin_lock(&up->port.lock); | ||
954 | |||
955 | /* | ||
956 | * First save the IER then disable the interrupts | ||
957 | */ | ||
958 | ier = serial_in(up, UART_IER); | ||
959 | serial_out(up, UART_IER, 0); | ||
960 | |||
961 | uart_console_write(&up->port, s, count, serial_omap_console_putchar); | ||
962 | |||
963 | /* | ||
964 | * Finally, wait for transmitter to become empty | ||
965 | * and restore the IER | ||
966 | */ | ||
967 | wait_for_xmitr(up); | ||
968 | serial_out(up, UART_IER, ier); | ||
969 | /* | ||
970 | * The receive handling will happen properly because the | ||
971 | * receive ready bit will still be set; it is not cleared | ||
972 | * on read. However, modem control will not, we must | ||
973 | * call it if we have saved something in the saved flags | ||
974 | * while processing with interrupts off. | ||
975 | */ | ||
976 | if (up->msr_saved_flags) | ||
977 | check_modem_status(up); | ||
978 | |||
979 | if (locked) | ||
980 | spin_unlock(&up->port.lock); | ||
981 | local_irq_restore(flags); | ||
982 | } | ||
983 | |||
984 | static int __init | ||
985 | serial_omap_console_setup(struct console *co, char *options) | ||
986 | { | ||
987 | struct uart_omap_port *up; | ||
988 | int baud = 115200; | ||
989 | int bits = 8; | ||
990 | int parity = 'n'; | ||
991 | int flow = 'n'; | ||
992 | |||
993 | if (serial_omap_console_ports[co->index] == NULL) | ||
994 | return -ENODEV; | ||
995 | up = serial_omap_console_ports[co->index]; | ||
996 | |||
997 | if (options) | ||
998 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
999 | |||
1000 | return uart_set_options(&up->port, co, baud, parity, bits, flow); | ||
1001 | } | ||
1002 | |||
1003 | static struct console serial_omap_console = { | ||
1004 | .name = OMAP_SERIAL_NAME, | ||
1005 | .write = serial_omap_console_write, | ||
1006 | .device = uart_console_device, | ||
1007 | .setup = serial_omap_console_setup, | ||
1008 | .flags = CON_PRINTBUFFER, | ||
1009 | .index = -1, | ||
1010 | .data = &serial_omap_reg, | ||
1011 | }; | ||
1012 | |||
1013 | static void serial_omap_add_console_port(struct uart_omap_port *up) | ||
1014 | { | ||
1015 | serial_omap_console_ports[up->pdev->id] = up; | ||
1016 | } | ||
1017 | |||
1018 | #define OMAP_CONSOLE (&serial_omap_console) | ||
1019 | |||
1020 | #else | ||
1021 | |||
1022 | #define OMAP_CONSOLE NULL | ||
1023 | |||
1024 | static inline void serial_omap_add_console_port(struct uart_omap_port *up) | ||
1025 | {} | ||
1026 | |||
1027 | #endif | ||
1028 | |||
1029 | static struct uart_ops serial_omap_pops = { | ||
1030 | .tx_empty = serial_omap_tx_empty, | ||
1031 | .set_mctrl = serial_omap_set_mctrl, | ||
1032 | .get_mctrl = serial_omap_get_mctrl, | ||
1033 | .stop_tx = serial_omap_stop_tx, | ||
1034 | .start_tx = serial_omap_start_tx, | ||
1035 | .stop_rx = serial_omap_stop_rx, | ||
1036 | .enable_ms = serial_omap_enable_ms, | ||
1037 | .break_ctl = serial_omap_break_ctl, | ||
1038 | .startup = serial_omap_startup, | ||
1039 | .shutdown = serial_omap_shutdown, | ||
1040 | .set_termios = serial_omap_set_termios, | ||
1041 | .pm = serial_omap_pm, | ||
1042 | .type = serial_omap_type, | ||
1043 | .release_port = serial_omap_release_port, | ||
1044 | .request_port = serial_omap_request_port, | ||
1045 | .config_port = serial_omap_config_port, | ||
1046 | .verify_port = serial_omap_verify_port, | ||
1047 | #ifdef CONFIG_CONSOLE_POLL | ||
1048 | .poll_put_char = serial_omap_poll_put_char, | ||
1049 | .poll_get_char = serial_omap_poll_get_char, | ||
1050 | #endif | ||
1051 | }; | ||
1052 | |||
1053 | static struct uart_driver serial_omap_reg = { | ||
1054 | .owner = THIS_MODULE, | ||
1055 | .driver_name = "OMAP-SERIAL", | ||
1056 | .dev_name = OMAP_SERIAL_NAME, | ||
1057 | .nr = OMAP_MAX_HSUART_PORTS, | ||
1058 | .cons = OMAP_CONSOLE, | ||
1059 | }; | ||
1060 | |||
1061 | static int | ||
1062 | serial_omap_suspend(struct platform_device *pdev, pm_message_t state) | ||
1063 | { | ||
1064 | struct uart_omap_port *up = platform_get_drvdata(pdev); | ||
1065 | |||
1066 | if (up) | ||
1067 | uart_suspend_port(&serial_omap_reg, &up->port); | ||
1068 | return 0; | ||
1069 | } | ||
1070 | |||
1071 | static int serial_omap_resume(struct platform_device *dev) | ||
1072 | { | ||
1073 | struct uart_omap_port *up = platform_get_drvdata(dev); | ||
1074 | |||
1075 | if (up) | ||
1076 | uart_resume_port(&serial_omap_reg, &up->port); | ||
1077 | return 0; | ||
1078 | } | ||
1079 | |||
1080 | static void serial_omap_rx_timeout(unsigned long uart_no) | ||
1081 | { | ||
1082 | struct uart_omap_port *up = ui[uart_no]; | ||
1083 | unsigned int curr_dma_pos, curr_transmitted_size; | ||
1084 | int ret = 0; | ||
1085 | |||
1086 | curr_dma_pos = omap_get_dma_dst_pos(up->uart_dma.rx_dma_channel); | ||
1087 | if ((curr_dma_pos == up->uart_dma.prev_rx_dma_pos) || | ||
1088 | (curr_dma_pos == 0)) { | ||
1089 | if (jiffies_to_msecs(jiffies - up->port_activity) < | ||
1090 | RX_TIMEOUT) { | ||
1091 | mod_timer(&up->uart_dma.rx_timer, jiffies + | ||
1092 | usecs_to_jiffies(up->uart_dma.rx_timeout)); | ||
1093 | } else { | ||
1094 | serial_omap_stop_rxdma(up); | ||
1095 | up->ier |= (UART_IER_RDI | UART_IER_RLSI); | ||
1096 | serial_out(up, UART_IER, up->ier); | ||
1097 | } | ||
1098 | return; | ||
1099 | } | ||
1100 | |||
1101 | curr_transmitted_size = curr_dma_pos - | ||
1102 | up->uart_dma.prev_rx_dma_pos; | ||
1103 | up->port.icount.rx += curr_transmitted_size; | ||
1104 | tty_insert_flip_string(up->port.state->port.tty, | ||
1105 | up->uart_dma.rx_buf + | ||
1106 | (up->uart_dma.prev_rx_dma_pos - | ||
1107 | up->uart_dma.rx_buf_dma_phys), | ||
1108 | curr_transmitted_size); | ||
1109 | tty_flip_buffer_push(up->port.state->port.tty); | ||
1110 | up->uart_dma.prev_rx_dma_pos = curr_dma_pos; | ||
1111 | if (up->uart_dma.rx_buf_size + | ||
1112 | up->uart_dma.rx_buf_dma_phys == curr_dma_pos) { | ||
1113 | ret = serial_omap_start_rxdma(up); | ||
1114 | if (ret < 0) { | ||
1115 | serial_omap_stop_rxdma(up); | ||
1116 | up->ier |= (UART_IER_RDI | UART_IER_RLSI); | ||
1117 | serial_out(up, UART_IER, up->ier); | ||
1118 | } | ||
1119 | } else { | ||
1120 | mod_timer(&up->uart_dma.rx_timer, jiffies + | ||
1121 | usecs_to_jiffies(up->uart_dma.rx_timeout)); | ||
1122 | } | ||
1123 | up->port_activity = jiffies; | ||
1124 | } | ||
1125 | |||
1126 | static void uart_rx_dma_callback(int lch, u16 ch_status, void *data) | ||
1127 | { | ||
1128 | return; | ||
1129 | } | ||
1130 | |||
1131 | static int serial_omap_start_rxdma(struct uart_omap_port *up) | ||
1132 | { | ||
1133 | int ret = 0; | ||
1134 | |||
1135 | if (up->uart_dma.rx_dma_channel == -1) { | ||
1136 | ret = omap_request_dma(up->uart_dma.uart_dma_rx, | ||
1137 | "UART Rx DMA", | ||
1138 | (void *)uart_rx_dma_callback, up, | ||
1139 | &(up->uart_dma.rx_dma_channel)); | ||
1140 | if (ret < 0) | ||
1141 | return ret; | ||
1142 | |||
1143 | omap_set_dma_src_params(up->uart_dma.rx_dma_channel, 0, | ||
1144 | OMAP_DMA_AMODE_CONSTANT, | ||
1145 | up->uart_dma.uart_base, 0, 0); | ||
1146 | omap_set_dma_dest_params(up->uart_dma.rx_dma_channel, 0, | ||
1147 | OMAP_DMA_AMODE_POST_INC, | ||
1148 | up->uart_dma.rx_buf_dma_phys, 0, 0); | ||
1149 | omap_set_dma_transfer_params(up->uart_dma.rx_dma_channel, | ||
1150 | OMAP_DMA_DATA_TYPE_S8, | ||
1151 | up->uart_dma.rx_buf_size, 1, | ||
1152 | OMAP_DMA_SYNC_ELEMENT, | ||
1153 | up->uart_dma.uart_dma_rx, 0); | ||
1154 | } | ||
1155 | up->uart_dma.prev_rx_dma_pos = up->uart_dma.rx_buf_dma_phys; | ||
1156 | /* FIXME: Cache maintenance needed here? */ | ||
1157 | omap_start_dma(up->uart_dma.rx_dma_channel); | ||
1158 | mod_timer(&up->uart_dma.rx_timer, jiffies + | ||
1159 | usecs_to_jiffies(up->uart_dma.rx_timeout)); | ||
1160 | up->uart_dma.rx_dma_used = true; | ||
1161 | return ret; | ||
1162 | } | ||
1163 | |||
1164 | static void serial_omap_continue_tx(struct uart_omap_port *up) | ||
1165 | { | ||
1166 | struct circ_buf *xmit = &up->port.state->xmit; | ||
1167 | unsigned int start = up->uart_dma.tx_buf_dma_phys | ||
1168 | + (xmit->tail & (UART_XMIT_SIZE - 1)); | ||
1169 | |||
1170 | if (uart_circ_empty(xmit)) | ||
1171 | return; | ||
1172 | |||
1173 | up->uart_dma.tx_buf_size = uart_circ_chars_pending(xmit); | ||
1174 | /* | ||
1175 | * It is a circular buffer. See if the buffer has wounded back. | ||
1176 | * If yes it will have to be transferred in two separate dma | ||
1177 | * transfers | ||
1178 | */ | ||
1179 | if (start + up->uart_dma.tx_buf_size >= | ||
1180 | up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE) | ||
1181 | up->uart_dma.tx_buf_size = | ||
1182 | (up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE) - start; | ||
1183 | omap_set_dma_dest_params(up->uart_dma.tx_dma_channel, 0, | ||
1184 | OMAP_DMA_AMODE_CONSTANT, | ||
1185 | up->uart_dma.uart_base, 0, 0); | ||
1186 | omap_set_dma_src_params(up->uart_dma.tx_dma_channel, 0, | ||
1187 | OMAP_DMA_AMODE_POST_INC, start, 0, 0); | ||
1188 | omap_set_dma_transfer_params(up->uart_dma.tx_dma_channel, | ||
1189 | OMAP_DMA_DATA_TYPE_S8, | ||
1190 | up->uart_dma.tx_buf_size, 1, | ||
1191 | OMAP_DMA_SYNC_ELEMENT, | ||
1192 | up->uart_dma.uart_dma_tx, 0); | ||
1193 | /* FIXME: Cache maintenance needed here? */ | ||
1194 | omap_start_dma(up->uart_dma.tx_dma_channel); | ||
1195 | } | ||
1196 | |||
1197 | static void uart_tx_dma_callback(int lch, u16 ch_status, void *data) | ||
1198 | { | ||
1199 | struct uart_omap_port *up = (struct uart_omap_port *)data; | ||
1200 | struct circ_buf *xmit = &up->port.state->xmit; | ||
1201 | |||
1202 | xmit->tail = (xmit->tail + up->uart_dma.tx_buf_size) & \ | ||
1203 | (UART_XMIT_SIZE - 1); | ||
1204 | up->port.icount.tx += up->uart_dma.tx_buf_size; | ||
1205 | |||
1206 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
1207 | uart_write_wakeup(&up->port); | ||
1208 | |||
1209 | if (uart_circ_empty(xmit)) { | ||
1210 | spin_lock(&(up->uart_dma.tx_lock)); | ||
1211 | serial_omap_stop_tx(&up->port); | ||
1212 | up->uart_dma.tx_dma_used = false; | ||
1213 | spin_unlock(&(up->uart_dma.tx_lock)); | ||
1214 | } else { | ||
1215 | omap_stop_dma(up->uart_dma.tx_dma_channel); | ||
1216 | serial_omap_continue_tx(up); | ||
1217 | } | ||
1218 | up->port_activity = jiffies; | ||
1219 | return; | ||
1220 | } | ||
1221 | |||
1222 | static int serial_omap_probe(struct platform_device *pdev) | ||
1223 | { | ||
1224 | struct uart_omap_port *up; | ||
1225 | struct resource *mem, *irq, *dma_tx, *dma_rx; | ||
1226 | struct omap_uart_port_info *omap_up_info = pdev->dev.platform_data; | ||
1227 | int ret = -ENOSPC; | ||
1228 | |||
1229 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1230 | if (!mem) { | ||
1231 | dev_err(&pdev->dev, "no mem resource?\n"); | ||
1232 | return -ENODEV; | ||
1233 | } | ||
1234 | |||
1235 | irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
1236 | if (!irq) { | ||
1237 | dev_err(&pdev->dev, "no irq resource?\n"); | ||
1238 | return -ENODEV; | ||
1239 | } | ||
1240 | |||
1241 | if (!request_mem_region(mem->start, (mem->end - mem->start) + 1, | ||
1242 | pdev->dev.driver->name)) { | ||
1243 | dev_err(&pdev->dev, "memory region already claimed\n"); | ||
1244 | return -EBUSY; | ||
1245 | } | ||
1246 | |||
1247 | dma_rx = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx"); | ||
1248 | if (!dma_rx) { | ||
1249 | ret = -EINVAL; | ||
1250 | goto err; | ||
1251 | } | ||
1252 | |||
1253 | dma_tx = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx"); | ||
1254 | if (!dma_tx) { | ||
1255 | ret = -EINVAL; | ||
1256 | goto err; | ||
1257 | } | ||
1258 | |||
1259 | up = kzalloc(sizeof(*up), GFP_KERNEL); | ||
1260 | if (up == NULL) { | ||
1261 | ret = -ENOMEM; | ||
1262 | goto do_release_region; | ||
1263 | } | ||
1264 | sprintf(up->name, "OMAP UART%d", pdev->id); | ||
1265 | up->pdev = pdev; | ||
1266 | up->port.dev = &pdev->dev; | ||
1267 | up->port.type = PORT_OMAP; | ||
1268 | up->port.iotype = UPIO_MEM; | ||
1269 | up->port.irq = irq->start; | ||
1270 | |||
1271 | up->port.regshift = 2; | ||
1272 | up->port.fifosize = 64; | ||
1273 | up->port.ops = &serial_omap_pops; | ||
1274 | up->port.line = pdev->id; | ||
1275 | |||
1276 | up->port.membase = omap_up_info->membase; | ||
1277 | up->port.mapbase = omap_up_info->mapbase; | ||
1278 | up->port.flags = omap_up_info->flags; | ||
1279 | up->port.irqflags = omap_up_info->irqflags; | ||
1280 | up->port.uartclk = omap_up_info->uartclk; | ||
1281 | up->uart_dma.uart_base = mem->start; | ||
1282 | |||
1283 | if (omap_up_info->dma_enabled) { | ||
1284 | up->uart_dma.uart_dma_tx = dma_tx->start; | ||
1285 | up->uart_dma.uart_dma_rx = dma_rx->start; | ||
1286 | up->use_dma = 1; | ||
1287 | up->uart_dma.rx_buf_size = 4096; | ||
1288 | up->uart_dma.rx_timeout = 2; | ||
1289 | spin_lock_init(&(up->uart_dma.tx_lock)); | ||
1290 | spin_lock_init(&(up->uart_dma.rx_lock)); | ||
1291 | up->uart_dma.tx_dma_channel = OMAP_UART_DMA_CH_FREE; | ||
1292 | up->uart_dma.rx_dma_channel = OMAP_UART_DMA_CH_FREE; | ||
1293 | } | ||
1294 | |||
1295 | ui[pdev->id] = up; | ||
1296 | serial_omap_add_console_port(up); | ||
1297 | |||
1298 | ret = uart_add_one_port(&serial_omap_reg, &up->port); | ||
1299 | if (ret != 0) | ||
1300 | goto do_release_region; | ||
1301 | |||
1302 | platform_set_drvdata(pdev, up); | ||
1303 | return 0; | ||
1304 | err: | ||
1305 | dev_err(&pdev->dev, "[UART%d]: failure [%s]: %d\n", | ||
1306 | pdev->id, __func__, ret); | ||
1307 | do_release_region: | ||
1308 | release_mem_region(mem->start, (mem->end - mem->start) + 1); | ||
1309 | return ret; | ||
1310 | } | ||
1311 | |||
1312 | static int serial_omap_remove(struct platform_device *dev) | ||
1313 | { | ||
1314 | struct uart_omap_port *up = platform_get_drvdata(dev); | ||
1315 | |||
1316 | platform_set_drvdata(dev, NULL); | ||
1317 | if (up) { | ||
1318 | uart_remove_one_port(&serial_omap_reg, &up->port); | ||
1319 | kfree(up); | ||
1320 | } | ||
1321 | return 0; | ||
1322 | } | ||
1323 | |||
1324 | static struct platform_driver serial_omap_driver = { | ||
1325 | .probe = serial_omap_probe, | ||
1326 | .remove = serial_omap_remove, | ||
1327 | |||
1328 | .suspend = serial_omap_suspend, | ||
1329 | .resume = serial_omap_resume, | ||
1330 | .driver = { | ||
1331 | .name = DRIVER_NAME, | ||
1332 | }, | ||
1333 | }; | ||
1334 | |||
1335 | static int __init serial_omap_init(void) | ||
1336 | { | ||
1337 | int ret; | ||
1338 | |||
1339 | ret = uart_register_driver(&serial_omap_reg); | ||
1340 | if (ret != 0) | ||
1341 | return ret; | ||
1342 | ret = platform_driver_register(&serial_omap_driver); | ||
1343 | if (ret != 0) | ||
1344 | uart_unregister_driver(&serial_omap_reg); | ||
1345 | return ret; | ||
1346 | } | ||
1347 | |||
1348 | static void __exit serial_omap_exit(void) | ||
1349 | { | ||
1350 | platform_driver_unregister(&serial_omap_driver); | ||
1351 | uart_unregister_driver(&serial_omap_reg); | ||
1352 | } | ||
1353 | |||
1354 | module_init(serial_omap_init); | ||
1355 | module_exit(serial_omap_exit); | ||
1356 | |||
1357 | MODULE_DESCRIPTION("OMAP High Speed UART driver"); | ||
1358 | MODULE_LICENSE("GPL"); | ||
1359 | MODULE_AUTHOR("Texas Instruments Inc"); | ||
diff --git a/drivers/serial/pch_uart.c b/drivers/serial/pch_uart.c new file mode 100644 index 000000000000..70a61458ec42 --- /dev/null +++ b/drivers/serial/pch_uart.c | |||
@@ -0,0 +1,1451 @@ | |||
1 | /* | ||
2 | *Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD. | ||
3 | * | ||
4 | *This program is free software; you can redistribute it and/or modify | ||
5 | *it under the terms of the GNU General Public License as published by | ||
6 | *the Free Software Foundation; version 2 of the License. | ||
7 | * | ||
8 | *This program is distributed in the hope that it will be useful, | ||
9 | *but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | *GNU General Public License for more details. | ||
12 | * | ||
13 | *You should have received a copy of the GNU General Public License | ||
14 | *along with this program; if not, write to the Free Software | ||
15 | *Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
16 | */ | ||
17 | #include <linux/serial_reg.h> | ||
18 | #include <linux/pci.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/pci.h> | ||
21 | #include <linux/serial_core.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | #include <linux/io.h> | ||
24 | |||
25 | #include <linux/dmaengine.h> | ||
26 | #include <linux/pch_dma.h> | ||
27 | |||
28 | enum { | ||
29 | PCH_UART_HANDLED_RX_INT_SHIFT, | ||
30 | PCH_UART_HANDLED_TX_INT_SHIFT, | ||
31 | PCH_UART_HANDLED_RX_ERR_INT_SHIFT, | ||
32 | PCH_UART_HANDLED_RX_TRG_INT_SHIFT, | ||
33 | PCH_UART_HANDLED_MS_INT_SHIFT, | ||
34 | }; | ||
35 | |||
36 | enum { | ||
37 | PCH_UART_8LINE, | ||
38 | PCH_UART_2LINE, | ||
39 | }; | ||
40 | |||
41 | #define PCH_UART_DRIVER_DEVICE "ttyPCH" | ||
42 | |||
43 | #define PCH_UART_NR_GE_256FIFO 1 | ||
44 | #define PCH_UART_NR_GE_64FIFO 3 | ||
45 | #define PCH_UART_NR_GE (PCH_UART_NR_GE_256FIFO+PCH_UART_NR_GE_64FIFO) | ||
46 | #define PCH_UART_NR PCH_UART_NR_GE | ||
47 | |||
48 | #define PCH_UART_HANDLED_RX_INT (1<<((PCH_UART_HANDLED_RX_INT_SHIFT)<<1)) | ||
49 | #define PCH_UART_HANDLED_TX_INT (1<<((PCH_UART_HANDLED_TX_INT_SHIFT)<<1)) | ||
50 | #define PCH_UART_HANDLED_RX_ERR_INT (1<<((\ | ||
51 | PCH_UART_HANDLED_RX_ERR_INT_SHIFT)<<1)) | ||
52 | #define PCH_UART_HANDLED_RX_TRG_INT (1<<((\ | ||
53 | PCH_UART_HANDLED_RX_TRG_INT_SHIFT)<<1)) | ||
54 | #define PCH_UART_HANDLED_MS_INT (1<<((PCH_UART_HANDLED_MS_INT_SHIFT)<<1)) | ||
55 | |||
56 | #define PCH_UART_RBR 0x00 | ||
57 | #define PCH_UART_THR 0x00 | ||
58 | |||
59 | #define PCH_UART_IER_MASK (PCH_UART_IER_ERBFI|PCH_UART_IER_ETBEI|\ | ||
60 | PCH_UART_IER_ELSI|PCH_UART_IER_EDSSI) | ||
61 | #define PCH_UART_IER_ERBFI 0x00000001 | ||
62 | #define PCH_UART_IER_ETBEI 0x00000002 | ||
63 | #define PCH_UART_IER_ELSI 0x00000004 | ||
64 | #define PCH_UART_IER_EDSSI 0x00000008 | ||
65 | |||
66 | #define PCH_UART_IIR_IP 0x00000001 | ||
67 | #define PCH_UART_IIR_IID 0x00000006 | ||
68 | #define PCH_UART_IIR_MSI 0x00000000 | ||
69 | #define PCH_UART_IIR_TRI 0x00000002 | ||
70 | #define PCH_UART_IIR_RRI 0x00000004 | ||
71 | #define PCH_UART_IIR_REI 0x00000006 | ||
72 | #define PCH_UART_IIR_TOI 0x00000008 | ||
73 | #define PCH_UART_IIR_FIFO256 0x00000020 | ||
74 | #define PCH_UART_IIR_FIFO64 PCH_UART_IIR_FIFO256 | ||
75 | #define PCH_UART_IIR_FE 0x000000C0 | ||
76 | |||
77 | #define PCH_UART_FCR_FIFOE 0x00000001 | ||
78 | #define PCH_UART_FCR_RFR 0x00000002 | ||
79 | #define PCH_UART_FCR_TFR 0x00000004 | ||
80 | #define PCH_UART_FCR_DMS 0x00000008 | ||
81 | #define PCH_UART_FCR_FIFO256 0x00000020 | ||
82 | #define PCH_UART_FCR_RFTL 0x000000C0 | ||
83 | |||
84 | #define PCH_UART_FCR_RFTL1 0x00000000 | ||
85 | #define PCH_UART_FCR_RFTL64 0x00000040 | ||
86 | #define PCH_UART_FCR_RFTL128 0x00000080 | ||
87 | #define PCH_UART_FCR_RFTL224 0x000000C0 | ||
88 | #define PCH_UART_FCR_RFTL16 PCH_UART_FCR_RFTL64 | ||
89 | #define PCH_UART_FCR_RFTL32 PCH_UART_FCR_RFTL128 | ||
90 | #define PCH_UART_FCR_RFTL56 PCH_UART_FCR_RFTL224 | ||
91 | #define PCH_UART_FCR_RFTL4 PCH_UART_FCR_RFTL64 | ||
92 | #define PCH_UART_FCR_RFTL8 PCH_UART_FCR_RFTL128 | ||
93 | #define PCH_UART_FCR_RFTL14 PCH_UART_FCR_RFTL224 | ||
94 | #define PCH_UART_FCR_RFTL_SHIFT 6 | ||
95 | |||
96 | #define PCH_UART_LCR_WLS 0x00000003 | ||
97 | #define PCH_UART_LCR_STB 0x00000004 | ||
98 | #define PCH_UART_LCR_PEN 0x00000008 | ||
99 | #define PCH_UART_LCR_EPS 0x00000010 | ||
100 | #define PCH_UART_LCR_SP 0x00000020 | ||
101 | #define PCH_UART_LCR_SB 0x00000040 | ||
102 | #define PCH_UART_LCR_DLAB 0x00000080 | ||
103 | #define PCH_UART_LCR_NP 0x00000000 | ||
104 | #define PCH_UART_LCR_OP PCH_UART_LCR_PEN | ||
105 | #define PCH_UART_LCR_EP (PCH_UART_LCR_PEN | PCH_UART_LCR_EPS) | ||
106 | #define PCH_UART_LCR_1P (PCH_UART_LCR_PEN | PCH_UART_LCR_SP) | ||
107 | #define PCH_UART_LCR_0P (PCH_UART_LCR_PEN | PCH_UART_LCR_EPS |\ | ||
108 | PCH_UART_LCR_SP) | ||
109 | |||
110 | #define PCH_UART_LCR_5BIT 0x00000000 | ||
111 | #define PCH_UART_LCR_6BIT 0x00000001 | ||
112 | #define PCH_UART_LCR_7BIT 0x00000002 | ||
113 | #define PCH_UART_LCR_8BIT 0x00000003 | ||
114 | |||
115 | #define PCH_UART_MCR_DTR 0x00000001 | ||
116 | #define PCH_UART_MCR_RTS 0x00000002 | ||
117 | #define PCH_UART_MCR_OUT 0x0000000C | ||
118 | #define PCH_UART_MCR_LOOP 0x00000010 | ||
119 | #define PCH_UART_MCR_AFE 0x00000020 | ||
120 | |||
121 | #define PCH_UART_LSR_DR 0x00000001 | ||
122 | #define PCH_UART_LSR_ERR (1<<7) | ||
123 | |||
124 | #define PCH_UART_MSR_DCTS 0x00000001 | ||
125 | #define PCH_UART_MSR_DDSR 0x00000002 | ||
126 | #define PCH_UART_MSR_TERI 0x00000004 | ||
127 | #define PCH_UART_MSR_DDCD 0x00000008 | ||
128 | #define PCH_UART_MSR_CTS 0x00000010 | ||
129 | #define PCH_UART_MSR_DSR 0x00000020 | ||
130 | #define PCH_UART_MSR_RI 0x00000040 | ||
131 | #define PCH_UART_MSR_DCD 0x00000080 | ||
132 | #define PCH_UART_MSR_DELTA (PCH_UART_MSR_DCTS | PCH_UART_MSR_DDSR |\ | ||
133 | PCH_UART_MSR_TERI | PCH_UART_MSR_DDCD) | ||
134 | |||
135 | #define PCH_UART_DLL 0x00 | ||
136 | #define PCH_UART_DLM 0x01 | ||
137 | |||
138 | #define DIV_ROUND(a, b) (((a) + ((b)/2)) / (b)) | ||
139 | |||
140 | #define PCH_UART_IID_RLS (PCH_UART_IIR_REI) | ||
141 | #define PCH_UART_IID_RDR (PCH_UART_IIR_RRI) | ||
142 | #define PCH_UART_IID_RDR_TO (PCH_UART_IIR_RRI | PCH_UART_IIR_TOI) | ||
143 | #define PCH_UART_IID_THRE (PCH_UART_IIR_TRI) | ||
144 | #define PCH_UART_IID_MS (PCH_UART_IIR_MSI) | ||
145 | |||
146 | #define PCH_UART_HAL_PARITY_NONE (PCH_UART_LCR_NP) | ||
147 | #define PCH_UART_HAL_PARITY_ODD (PCH_UART_LCR_OP) | ||
148 | #define PCH_UART_HAL_PARITY_EVEN (PCH_UART_LCR_EP) | ||
149 | #define PCH_UART_HAL_PARITY_FIX1 (PCH_UART_LCR_1P) | ||
150 | #define PCH_UART_HAL_PARITY_FIX0 (PCH_UART_LCR_0P) | ||
151 | #define PCH_UART_HAL_5BIT (PCH_UART_LCR_5BIT) | ||
152 | #define PCH_UART_HAL_6BIT (PCH_UART_LCR_6BIT) | ||
153 | #define PCH_UART_HAL_7BIT (PCH_UART_LCR_7BIT) | ||
154 | #define PCH_UART_HAL_8BIT (PCH_UART_LCR_8BIT) | ||
155 | #define PCH_UART_HAL_STB1 0 | ||
156 | #define PCH_UART_HAL_STB2 (PCH_UART_LCR_STB) | ||
157 | |||
158 | #define PCH_UART_HAL_CLR_TX_FIFO (PCH_UART_FCR_TFR) | ||
159 | #define PCH_UART_HAL_CLR_RX_FIFO (PCH_UART_FCR_RFR) | ||
160 | #define PCH_UART_HAL_CLR_ALL_FIFO (PCH_UART_HAL_CLR_TX_FIFO | \ | ||
161 | PCH_UART_HAL_CLR_RX_FIFO) | ||
162 | |||
163 | #define PCH_UART_HAL_DMA_MODE0 0 | ||
164 | #define PCH_UART_HAL_FIFO_DIS 0 | ||
165 | #define PCH_UART_HAL_FIFO16 (PCH_UART_FCR_FIFOE) | ||
166 | #define PCH_UART_HAL_FIFO256 (PCH_UART_FCR_FIFOE | \ | ||
167 | PCH_UART_FCR_FIFO256) | ||
168 | #define PCH_UART_HAL_FIFO64 (PCH_UART_HAL_FIFO256) | ||
169 | #define PCH_UART_HAL_TRIGGER1 (PCH_UART_FCR_RFTL1) | ||
170 | #define PCH_UART_HAL_TRIGGER64 (PCH_UART_FCR_RFTL64) | ||
171 | #define PCH_UART_HAL_TRIGGER128 (PCH_UART_FCR_RFTL128) | ||
172 | #define PCH_UART_HAL_TRIGGER224 (PCH_UART_FCR_RFTL224) | ||
173 | #define PCH_UART_HAL_TRIGGER16 (PCH_UART_FCR_RFTL16) | ||
174 | #define PCH_UART_HAL_TRIGGER32 (PCH_UART_FCR_RFTL32) | ||
175 | #define PCH_UART_HAL_TRIGGER56 (PCH_UART_FCR_RFTL56) | ||
176 | #define PCH_UART_HAL_TRIGGER4 (PCH_UART_FCR_RFTL4) | ||
177 | #define PCH_UART_HAL_TRIGGER8 (PCH_UART_FCR_RFTL8) | ||
178 | #define PCH_UART_HAL_TRIGGER14 (PCH_UART_FCR_RFTL14) | ||
179 | #define PCH_UART_HAL_TRIGGER_L (PCH_UART_FCR_RFTL64) | ||
180 | #define PCH_UART_HAL_TRIGGER_M (PCH_UART_FCR_RFTL128) | ||
181 | #define PCH_UART_HAL_TRIGGER_H (PCH_UART_FCR_RFTL224) | ||
182 | |||
183 | #define PCH_UART_HAL_RX_INT (PCH_UART_IER_ERBFI) | ||
184 | #define PCH_UART_HAL_TX_INT (PCH_UART_IER_ETBEI) | ||
185 | #define PCH_UART_HAL_RX_ERR_INT (PCH_UART_IER_ELSI) | ||
186 | #define PCH_UART_HAL_MS_INT (PCH_UART_IER_EDSSI) | ||
187 | #define PCH_UART_HAL_ALL_INT (PCH_UART_IER_MASK) | ||
188 | |||
189 | #define PCH_UART_HAL_DTR (PCH_UART_MCR_DTR) | ||
190 | #define PCH_UART_HAL_RTS (PCH_UART_MCR_RTS) | ||
191 | #define PCH_UART_HAL_OUT (PCH_UART_MCR_OUT) | ||
192 | #define PCH_UART_HAL_LOOP (PCH_UART_MCR_LOOP) | ||
193 | #define PCH_UART_HAL_AFE (PCH_UART_MCR_AFE) | ||
194 | |||
195 | struct pch_uart_buffer { | ||
196 | unsigned char *buf; | ||
197 | int size; | ||
198 | }; | ||
199 | |||
200 | struct eg20t_port { | ||
201 | struct uart_port port; | ||
202 | int port_type; | ||
203 | void __iomem *membase; | ||
204 | resource_size_t mapbase; | ||
205 | unsigned int iobase; | ||
206 | struct pci_dev *pdev; | ||
207 | int fifo_size; | ||
208 | int base_baud; | ||
209 | int start_tx; | ||
210 | int start_rx; | ||
211 | int tx_empty; | ||
212 | int int_dis_flag; | ||
213 | int trigger; | ||
214 | int trigger_level; | ||
215 | struct pch_uart_buffer rxbuf; | ||
216 | unsigned int dmsr; | ||
217 | unsigned int fcr; | ||
218 | unsigned int use_dma; | ||
219 | unsigned int use_dma_flag; | ||
220 | struct dma_async_tx_descriptor *desc_tx; | ||
221 | struct dma_async_tx_descriptor *desc_rx; | ||
222 | struct pch_dma_slave param_tx; | ||
223 | struct pch_dma_slave param_rx; | ||
224 | struct dma_chan *chan_tx; | ||
225 | struct dma_chan *chan_rx; | ||
226 | struct scatterlist sg_tx; | ||
227 | struct scatterlist sg_rx; | ||
228 | int tx_dma_use; | ||
229 | void *rx_buf_virt; | ||
230 | dma_addr_t rx_buf_dma; | ||
231 | }; | ||
232 | |||
233 | static unsigned int default_baud = 9600; | ||
234 | static const int trigger_level_256[4] = { 1, 64, 128, 224 }; | ||
235 | static const int trigger_level_64[4] = { 1, 16, 32, 56 }; | ||
236 | static const int trigger_level_16[4] = { 1, 4, 8, 14 }; | ||
237 | static const int trigger_level_1[4] = { 1, 1, 1, 1 }; | ||
238 | |||
239 | static void pch_uart_hal_request(struct pci_dev *pdev, int fifosize, | ||
240 | int base_baud) | ||
241 | { | ||
242 | struct eg20t_port *priv = pci_get_drvdata(pdev); | ||
243 | |||
244 | priv->trigger_level = 1; | ||
245 | priv->fcr = 0; | ||
246 | } | ||
247 | |||
248 | static unsigned int get_msr(struct eg20t_port *priv, void __iomem *base) | ||
249 | { | ||
250 | unsigned int msr = ioread8(base + UART_MSR); | ||
251 | priv->dmsr |= msr & PCH_UART_MSR_DELTA; | ||
252 | |||
253 | return msr; | ||
254 | } | ||
255 | |||
256 | static void pch_uart_hal_enable_interrupt(struct eg20t_port *priv, | ||
257 | unsigned int flag) | ||
258 | { | ||
259 | u8 ier = ioread8(priv->membase + UART_IER); | ||
260 | ier |= flag & PCH_UART_IER_MASK; | ||
261 | iowrite8(ier, priv->membase + UART_IER); | ||
262 | } | ||
263 | |||
264 | static void pch_uart_hal_disable_interrupt(struct eg20t_port *priv, | ||
265 | unsigned int flag) | ||
266 | { | ||
267 | u8 ier = ioread8(priv->membase + UART_IER); | ||
268 | ier &= ~(flag & PCH_UART_IER_MASK); | ||
269 | iowrite8(ier, priv->membase + UART_IER); | ||
270 | } | ||
271 | |||
272 | static int pch_uart_hal_set_line(struct eg20t_port *priv, int baud, | ||
273 | unsigned int parity, unsigned int bits, | ||
274 | unsigned int stb) | ||
275 | { | ||
276 | unsigned int dll, dlm, lcr; | ||
277 | int div; | ||
278 | |||
279 | div = DIV_ROUND(priv->base_baud / 16, baud); | ||
280 | if (div < 0 || USHRT_MAX <= div) { | ||
281 | pr_err("Invalid Baud(div=0x%x)\n", div); | ||
282 | return -EINVAL; | ||
283 | } | ||
284 | |||
285 | dll = (unsigned int)div & 0x00FFU; | ||
286 | dlm = ((unsigned int)div >> 8) & 0x00FFU; | ||
287 | |||
288 | if (parity & ~(PCH_UART_LCR_PEN | PCH_UART_LCR_EPS | PCH_UART_LCR_SP)) { | ||
289 | pr_err("Invalid parity(0x%x)\n", parity); | ||
290 | return -EINVAL; | ||
291 | } | ||
292 | |||
293 | if (bits & ~PCH_UART_LCR_WLS) { | ||
294 | pr_err("Invalid bits(0x%x)\n", bits); | ||
295 | return -EINVAL; | ||
296 | } | ||
297 | |||
298 | if (stb & ~PCH_UART_LCR_STB) { | ||
299 | pr_err("Invalid STB(0x%x)\n", stb); | ||
300 | return -EINVAL; | ||
301 | } | ||
302 | |||
303 | lcr = parity; | ||
304 | lcr |= bits; | ||
305 | lcr |= stb; | ||
306 | |||
307 | pr_debug("%s:baud = %d, div = %04x, lcr = %02x (%lu)\n", | ||
308 | __func__, baud, div, lcr, jiffies); | ||
309 | iowrite8(PCH_UART_LCR_DLAB, priv->membase + UART_LCR); | ||
310 | iowrite8(dll, priv->membase + PCH_UART_DLL); | ||
311 | iowrite8(dlm, priv->membase + PCH_UART_DLM); | ||
312 | iowrite8(lcr, priv->membase + UART_LCR); | ||
313 | |||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | static int pch_uart_hal_fifo_reset(struct eg20t_port *priv, | ||
318 | unsigned int flag) | ||
319 | { | ||
320 | if (flag & ~(PCH_UART_FCR_TFR | PCH_UART_FCR_RFR)) { | ||
321 | pr_err("%s:Invalid flag(0x%x)\n", __func__, flag); | ||
322 | return -EINVAL; | ||
323 | } | ||
324 | |||
325 | iowrite8(PCH_UART_FCR_FIFOE | priv->fcr, priv->membase + UART_FCR); | ||
326 | iowrite8(PCH_UART_FCR_FIFOE | priv->fcr | flag, | ||
327 | priv->membase + UART_FCR); | ||
328 | iowrite8(priv->fcr, priv->membase + UART_FCR); | ||
329 | |||
330 | return 0; | ||
331 | } | ||
332 | |||
333 | static int pch_uart_hal_set_fifo(struct eg20t_port *priv, | ||
334 | unsigned int dmamode, | ||
335 | unsigned int fifo_size, unsigned int trigger) | ||
336 | { | ||
337 | u8 fcr; | ||
338 | |||
339 | if (dmamode & ~PCH_UART_FCR_DMS) { | ||
340 | pr_err("%s:Invalid DMA Mode(0x%x)\n", __func__, dmamode); | ||
341 | return -EINVAL; | ||
342 | } | ||
343 | |||
344 | if (fifo_size & ~(PCH_UART_FCR_FIFOE | PCH_UART_FCR_FIFO256)) { | ||
345 | pr_err("%s:Invalid FIFO SIZE(0x%x)\n", __func__, fifo_size); | ||
346 | return -EINVAL; | ||
347 | } | ||
348 | |||
349 | if (trigger & ~PCH_UART_FCR_RFTL) { | ||
350 | pr_err("%s:Invalid TRIGGER(0x%x)\n", __func__, trigger); | ||
351 | return -EINVAL; | ||
352 | } | ||
353 | |||
354 | switch (priv->fifo_size) { | ||
355 | case 256: | ||
356 | priv->trigger_level = | ||
357 | trigger_level_256[trigger >> PCH_UART_FCR_RFTL_SHIFT]; | ||
358 | break; | ||
359 | case 64: | ||
360 | priv->trigger_level = | ||
361 | trigger_level_64[trigger >> PCH_UART_FCR_RFTL_SHIFT]; | ||
362 | break; | ||
363 | case 16: | ||
364 | priv->trigger_level = | ||
365 | trigger_level_16[trigger >> PCH_UART_FCR_RFTL_SHIFT]; | ||
366 | break; | ||
367 | default: | ||
368 | priv->trigger_level = | ||
369 | trigger_level_1[trigger >> PCH_UART_FCR_RFTL_SHIFT]; | ||
370 | break; | ||
371 | } | ||
372 | fcr = | ||
373 | dmamode | fifo_size | trigger | PCH_UART_FCR_RFR | PCH_UART_FCR_TFR; | ||
374 | iowrite8(PCH_UART_FCR_FIFOE, priv->membase + UART_FCR); | ||
375 | iowrite8(PCH_UART_FCR_FIFOE | PCH_UART_FCR_RFR | PCH_UART_FCR_TFR, | ||
376 | priv->membase + UART_FCR); | ||
377 | iowrite8(fcr, priv->membase + UART_FCR); | ||
378 | priv->fcr = fcr; | ||
379 | |||
380 | return 0; | ||
381 | } | ||
382 | |||
383 | static u8 pch_uart_hal_get_modem(struct eg20t_port *priv) | ||
384 | { | ||
385 | priv->dmsr = 0; | ||
386 | return get_msr(priv, priv->membase); | ||
387 | } | ||
388 | |||
389 | static int pch_uart_hal_write(struct eg20t_port *priv, | ||
390 | const unsigned char *buf, int tx_size) | ||
391 | { | ||
392 | int i; | ||
393 | unsigned int thr; | ||
394 | |||
395 | for (i = 0; i < tx_size;) { | ||
396 | thr = buf[i++]; | ||
397 | iowrite8(thr, priv->membase + PCH_UART_THR); | ||
398 | } | ||
399 | return i; | ||
400 | } | ||
401 | |||
402 | static int pch_uart_hal_read(struct eg20t_port *priv, unsigned char *buf, | ||
403 | int rx_size) | ||
404 | { | ||
405 | int i; | ||
406 | u8 rbr, lsr; | ||
407 | |||
408 | lsr = ioread8(priv->membase + UART_LSR); | ||
409 | for (i = 0, lsr = ioread8(priv->membase + UART_LSR); | ||
410 | i < rx_size && lsr & UART_LSR_DR; | ||
411 | lsr = ioread8(priv->membase + UART_LSR)) { | ||
412 | rbr = ioread8(priv->membase + PCH_UART_RBR); | ||
413 | buf[i++] = rbr; | ||
414 | } | ||
415 | return i; | ||
416 | } | ||
417 | |||
418 | static unsigned int pch_uart_hal_get_iid(struct eg20t_port *priv) | ||
419 | { | ||
420 | unsigned int iir; | ||
421 | int ret; | ||
422 | |||
423 | iir = ioread8(priv->membase + UART_IIR); | ||
424 | ret = (iir & (PCH_UART_IIR_IID | PCH_UART_IIR_TOI | PCH_UART_IIR_IP)); | ||
425 | return ret; | ||
426 | } | ||
427 | |||
428 | static u8 pch_uart_hal_get_line_status(struct eg20t_port *priv) | ||
429 | { | ||
430 | return ioread8(priv->membase + UART_LSR); | ||
431 | } | ||
432 | |||
433 | static void pch_uart_hal_set_break(struct eg20t_port *priv, int on) | ||
434 | { | ||
435 | unsigned int lcr; | ||
436 | |||
437 | lcr = ioread8(priv->membase + UART_LCR); | ||
438 | if (on) | ||
439 | lcr |= PCH_UART_LCR_SB; | ||
440 | else | ||
441 | lcr &= ~PCH_UART_LCR_SB; | ||
442 | |||
443 | iowrite8(lcr, priv->membase + UART_LCR); | ||
444 | } | ||
445 | |||
446 | static int push_rx(struct eg20t_port *priv, const unsigned char *buf, | ||
447 | int size) | ||
448 | { | ||
449 | struct uart_port *port; | ||
450 | struct tty_struct *tty; | ||
451 | |||
452 | port = &priv->port; | ||
453 | tty = tty_port_tty_get(&port->state->port); | ||
454 | if (!tty) { | ||
455 | pr_debug("%s:tty is busy now", __func__); | ||
456 | return -EBUSY; | ||
457 | } | ||
458 | |||
459 | tty_insert_flip_string(tty, buf, size); | ||
460 | tty_flip_buffer_push(tty); | ||
461 | tty_kref_put(tty); | ||
462 | |||
463 | return 0; | ||
464 | } | ||
465 | |||
466 | static int pop_tx_x(struct eg20t_port *priv, unsigned char *buf) | ||
467 | { | ||
468 | int ret; | ||
469 | struct uart_port *port = &priv->port; | ||
470 | |||
471 | if (port->x_char) { | ||
472 | pr_debug("%s:X character send %02x (%lu)\n", __func__, | ||
473 | port->x_char, jiffies); | ||
474 | buf[0] = port->x_char; | ||
475 | port->x_char = 0; | ||
476 | ret = 1; | ||
477 | } else { | ||
478 | ret = 0; | ||
479 | } | ||
480 | |||
481 | return ret; | ||
482 | } | ||
483 | |||
484 | static int dma_push_rx(struct eg20t_port *priv, int size) | ||
485 | { | ||
486 | struct tty_struct *tty; | ||
487 | int room; | ||
488 | struct uart_port *port = &priv->port; | ||
489 | |||
490 | port = &priv->port; | ||
491 | tty = tty_port_tty_get(&port->state->port); | ||
492 | if (!tty) { | ||
493 | pr_debug("%s:tty is busy now", __func__); | ||
494 | return 0; | ||
495 | } | ||
496 | |||
497 | room = tty_buffer_request_room(tty, size); | ||
498 | |||
499 | if (room < size) | ||
500 | dev_warn(port->dev, "Rx overrun: dropping %u bytes\n", | ||
501 | size - room); | ||
502 | if (!room) | ||
503 | return room; | ||
504 | |||
505 | tty_insert_flip_string(tty, sg_virt(&priv->sg_rx), size); | ||
506 | |||
507 | port->icount.rx += room; | ||
508 | tty_kref_put(tty); | ||
509 | |||
510 | return room; | ||
511 | } | ||
512 | |||
513 | static void pch_free_dma(struct uart_port *port) | ||
514 | { | ||
515 | struct eg20t_port *priv; | ||
516 | priv = container_of(port, struct eg20t_port, port); | ||
517 | |||
518 | if (priv->chan_tx) { | ||
519 | dma_release_channel(priv->chan_tx); | ||
520 | priv->chan_tx = NULL; | ||
521 | } | ||
522 | if (priv->chan_rx) { | ||
523 | dma_release_channel(priv->chan_rx); | ||
524 | priv->chan_rx = NULL; | ||
525 | } | ||
526 | if (sg_dma_address(&priv->sg_rx)) | ||
527 | dma_free_coherent(port->dev, port->fifosize, | ||
528 | sg_virt(&priv->sg_rx), | ||
529 | sg_dma_address(&priv->sg_rx)); | ||
530 | |||
531 | return; | ||
532 | } | ||
533 | |||
534 | static bool filter(struct dma_chan *chan, void *slave) | ||
535 | { | ||
536 | struct pch_dma_slave *param = slave; | ||
537 | |||
538 | if ((chan->chan_id == param->chan_id) && (param->dma_dev == | ||
539 | chan->device->dev)) { | ||
540 | chan->private = param; | ||
541 | return true; | ||
542 | } else { | ||
543 | return false; | ||
544 | } | ||
545 | } | ||
546 | |||
547 | static void pch_request_dma(struct uart_port *port) | ||
548 | { | ||
549 | dma_cap_mask_t mask; | ||
550 | struct dma_chan *chan; | ||
551 | struct pci_dev *dma_dev; | ||
552 | struct pch_dma_slave *param; | ||
553 | struct eg20t_port *priv = | ||
554 | container_of(port, struct eg20t_port, port); | ||
555 | dma_cap_zero(mask); | ||
556 | dma_cap_set(DMA_SLAVE, mask); | ||
557 | |||
558 | dma_dev = pci_get_bus_and_slot(2, PCI_DEVFN(0xa, 0)); /* Get DMA's dev | ||
559 | information */ | ||
560 | /* Set Tx DMA */ | ||
561 | param = &priv->param_tx; | ||
562 | param->dma_dev = &dma_dev->dev; | ||
563 | param->chan_id = priv->port.line; | ||
564 | param->tx_reg = port->mapbase + UART_TX; | ||
565 | chan = dma_request_channel(mask, filter, param); | ||
566 | if (!chan) { | ||
567 | pr_err("%s:dma_request_channel FAILS(Tx)\n", __func__); | ||
568 | return; | ||
569 | } | ||
570 | priv->chan_tx = chan; | ||
571 | |||
572 | /* Set Rx DMA */ | ||
573 | param = &priv->param_rx; | ||
574 | param->dma_dev = &dma_dev->dev; | ||
575 | param->chan_id = priv->port.line + 1; /* Rx = Tx + 1 */ | ||
576 | param->rx_reg = port->mapbase + UART_RX; | ||
577 | chan = dma_request_channel(mask, filter, param); | ||
578 | if (!chan) { | ||
579 | pr_err("%s:dma_request_channel FAILS(Rx)\n", __func__); | ||
580 | dma_release_channel(priv->chan_tx); | ||
581 | return; | ||
582 | } | ||
583 | |||
584 | /* Get Consistent memory for DMA */ | ||
585 | priv->rx_buf_virt = dma_alloc_coherent(port->dev, port->fifosize, | ||
586 | &priv->rx_buf_dma, GFP_KERNEL); | ||
587 | priv->chan_rx = chan; | ||
588 | } | ||
589 | |||
590 | static void pch_dma_rx_complete(void *arg) | ||
591 | { | ||
592 | struct eg20t_port *priv = arg; | ||
593 | struct uart_port *port = &priv->port; | ||
594 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | ||
595 | |||
596 | if (!tty) { | ||
597 | pr_debug("%s:tty is busy now", __func__); | ||
598 | return; | ||
599 | } | ||
600 | |||
601 | if (dma_push_rx(priv, priv->trigger_level)) | ||
602 | tty_flip_buffer_push(tty); | ||
603 | |||
604 | tty_kref_put(tty); | ||
605 | } | ||
606 | |||
607 | static void pch_dma_tx_complete(void *arg) | ||
608 | { | ||
609 | struct eg20t_port *priv = arg; | ||
610 | struct uart_port *port = &priv->port; | ||
611 | struct circ_buf *xmit = &port->state->xmit; | ||
612 | |||
613 | xmit->tail += sg_dma_len(&priv->sg_tx); | ||
614 | xmit->tail &= UART_XMIT_SIZE - 1; | ||
615 | port->icount.tx += sg_dma_len(&priv->sg_tx); | ||
616 | |||
617 | async_tx_ack(priv->desc_tx); | ||
618 | priv->tx_dma_use = 0; | ||
619 | } | ||
620 | |||
621 | static int pop_tx(struct eg20t_port *priv, unsigned char *buf, int size) | ||
622 | { | ||
623 | int count = 0; | ||
624 | struct uart_port *port = &priv->port; | ||
625 | struct circ_buf *xmit = &port->state->xmit; | ||
626 | |||
627 | if (uart_tx_stopped(port) || uart_circ_empty(xmit) || count >= size) | ||
628 | goto pop_tx_end; | ||
629 | |||
630 | do { | ||
631 | int cnt_to_end = | ||
632 | CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); | ||
633 | int sz = min(size - count, cnt_to_end); | ||
634 | memcpy(&buf[count], &xmit->buf[xmit->tail], sz); | ||
635 | xmit->tail = (xmit->tail + sz) & (UART_XMIT_SIZE - 1); | ||
636 | count += sz; | ||
637 | } while (!uart_circ_empty(xmit) && count < size); | ||
638 | |||
639 | pop_tx_end: | ||
640 | pr_debug("%d characters. Remained %d characters. (%lu)\n", | ||
641 | count, size - count, jiffies); | ||
642 | |||
643 | return count; | ||
644 | } | ||
645 | |||
646 | static int handle_rx_to(struct eg20t_port *priv) | ||
647 | { | ||
648 | struct pch_uart_buffer *buf; | ||
649 | int rx_size; | ||
650 | int ret; | ||
651 | if (!priv->start_rx) { | ||
652 | pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_RX_INT); | ||
653 | return 0; | ||
654 | } | ||
655 | buf = &priv->rxbuf; | ||
656 | do { | ||
657 | rx_size = pch_uart_hal_read(priv, buf->buf, buf->size); | ||
658 | ret = push_rx(priv, buf->buf, rx_size); | ||
659 | if (ret) | ||
660 | return 0; | ||
661 | } while (rx_size == buf->size); | ||
662 | |||
663 | return PCH_UART_HANDLED_RX_INT; | ||
664 | } | ||
665 | |||
666 | static int handle_rx(struct eg20t_port *priv) | ||
667 | { | ||
668 | return handle_rx_to(priv); | ||
669 | } | ||
670 | |||
671 | static int dma_handle_rx(struct eg20t_port *priv) | ||
672 | { | ||
673 | struct uart_port *port = &priv->port; | ||
674 | struct dma_async_tx_descriptor *desc; | ||
675 | struct scatterlist *sg; | ||
676 | |||
677 | priv = container_of(port, struct eg20t_port, port); | ||
678 | sg = &priv->sg_rx; | ||
679 | |||
680 | sg_init_table(&priv->sg_rx, 1); /* Initialize SG table */ | ||
681 | |||
682 | sg_dma_len(sg) = priv->fifo_size; | ||
683 | |||
684 | sg_set_page(&priv->sg_rx, virt_to_page(priv->rx_buf_virt), | ||
685 | sg_dma_len(sg), (unsigned long)priv->rx_buf_virt & | ||
686 | ~PAGE_MASK); | ||
687 | |||
688 | sg_dma_address(sg) = priv->rx_buf_dma; | ||
689 | |||
690 | desc = priv->chan_rx->device->device_prep_slave_sg(priv->chan_rx, | ||
691 | sg, 1, DMA_FROM_DEVICE, | ||
692 | DMA_PREP_INTERRUPT); | ||
693 | if (!desc) | ||
694 | return 0; | ||
695 | |||
696 | priv->desc_rx = desc; | ||
697 | desc->callback = pch_dma_rx_complete; | ||
698 | desc->callback_param = priv; | ||
699 | desc->tx_submit(desc); | ||
700 | dma_async_issue_pending(priv->chan_rx); | ||
701 | |||
702 | return PCH_UART_HANDLED_RX_INT; | ||
703 | } | ||
704 | |||
705 | static unsigned int handle_tx(struct eg20t_port *priv) | ||
706 | { | ||
707 | struct uart_port *port = &priv->port; | ||
708 | struct circ_buf *xmit = &port->state->xmit; | ||
709 | int ret; | ||
710 | int fifo_size; | ||
711 | int tx_size; | ||
712 | int size; | ||
713 | int tx_empty; | ||
714 | |||
715 | if (!priv->start_tx) { | ||
716 | pr_info("%s:Tx isn't started. (%lu)\n", __func__, jiffies); | ||
717 | pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_TX_INT); | ||
718 | priv->tx_empty = 1; | ||
719 | return 0; | ||
720 | } | ||
721 | |||
722 | fifo_size = max(priv->fifo_size, 1); | ||
723 | tx_empty = 1; | ||
724 | if (pop_tx_x(priv, xmit->buf)) { | ||
725 | pch_uart_hal_write(priv, xmit->buf, 1); | ||
726 | port->icount.tx++; | ||
727 | tx_empty = 0; | ||
728 | fifo_size--; | ||
729 | } | ||
730 | size = min(xmit->head - xmit->tail, fifo_size); | ||
731 | tx_size = pop_tx(priv, xmit->buf, size); | ||
732 | if (tx_size > 0) { | ||
733 | ret = pch_uart_hal_write(priv, xmit->buf, tx_size); | ||
734 | port->icount.tx += ret; | ||
735 | tx_empty = 0; | ||
736 | } | ||
737 | |||
738 | priv->tx_empty = tx_empty; | ||
739 | |||
740 | if (tx_empty) | ||
741 | pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_TX_INT); | ||
742 | |||
743 | return PCH_UART_HANDLED_TX_INT; | ||
744 | } | ||
745 | |||
746 | static unsigned int dma_handle_tx(struct eg20t_port *priv) | ||
747 | { | ||
748 | struct uart_port *port = &priv->port; | ||
749 | struct circ_buf *xmit = &port->state->xmit; | ||
750 | struct scatterlist *sg = &priv->sg_tx; | ||
751 | int nent; | ||
752 | int fifo_size; | ||
753 | int tx_empty; | ||
754 | struct dma_async_tx_descriptor *desc; | ||
755 | |||
756 | if (!priv->start_tx) { | ||
757 | pr_info("%s:Tx isn't started. (%lu)\n", __func__, jiffies); | ||
758 | pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_TX_INT); | ||
759 | priv->tx_empty = 1; | ||
760 | return 0; | ||
761 | } | ||
762 | |||
763 | fifo_size = max(priv->fifo_size, 1); | ||
764 | tx_empty = 1; | ||
765 | if (pop_tx_x(priv, xmit->buf)) { | ||
766 | pch_uart_hal_write(priv, xmit->buf, 1); | ||
767 | port->icount.tx++; | ||
768 | tx_empty = 0; | ||
769 | fifo_size--; | ||
770 | } | ||
771 | |||
772 | pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_TX_INT); | ||
773 | |||
774 | priv->tx_dma_use = 1; | ||
775 | |||
776 | sg_init_table(&priv->sg_tx, 1); /* Initialize SG table */ | ||
777 | |||
778 | sg_set_page(&priv->sg_tx, virt_to_page(xmit->buf), | ||
779 | UART_XMIT_SIZE, (int)xmit->buf & ~PAGE_MASK); | ||
780 | |||
781 | nent = dma_map_sg(port->dev, &priv->sg_tx, 1, DMA_TO_DEVICE); | ||
782 | if (!nent) { | ||
783 | pr_err("%s:dma_map_sg Failed\n", __func__); | ||
784 | return 0; | ||
785 | } | ||
786 | |||
787 | sg->offset = xmit->tail & (UART_XMIT_SIZE - 1); | ||
788 | sg_dma_address(sg) = (sg_dma_address(sg) & ~(UART_XMIT_SIZE - 1)) + | ||
789 | sg->offset; | ||
790 | sg_dma_len(sg) = min((int)CIRC_CNT(xmit->head, xmit->tail, | ||
791 | UART_XMIT_SIZE), CIRC_CNT_TO_END(xmit->head, | ||
792 | xmit->tail, UART_XMIT_SIZE)); | ||
793 | |||
794 | desc = priv->chan_tx->device->device_prep_slave_sg(priv->chan_tx, | ||
795 | sg, nent, DMA_TO_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
796 | if (!desc) { | ||
797 | pr_err("%s:device_prep_slave_sg Failed\n", __func__); | ||
798 | return 0; | ||
799 | } | ||
800 | |||
801 | dma_sync_sg_for_device(port->dev, sg, 1, DMA_TO_DEVICE); | ||
802 | |||
803 | priv->desc_tx = desc; | ||
804 | desc->callback = pch_dma_tx_complete; | ||
805 | desc->callback_param = priv; | ||
806 | |||
807 | desc->tx_submit(desc); | ||
808 | |||
809 | dma_async_issue_pending(priv->chan_tx); | ||
810 | |||
811 | return PCH_UART_HANDLED_TX_INT; | ||
812 | } | ||
813 | |||
814 | static void pch_uart_err_ir(struct eg20t_port *priv, unsigned int lsr) | ||
815 | { | ||
816 | u8 fcr = ioread8(priv->membase + UART_FCR); | ||
817 | |||
818 | /* Reset FIFO */ | ||
819 | fcr |= UART_FCR_CLEAR_RCVR; | ||
820 | iowrite8(fcr, priv->membase + UART_FCR); | ||
821 | |||
822 | if (lsr & PCH_UART_LSR_ERR) | ||
823 | dev_err(&priv->pdev->dev, "Error data in FIFO\n"); | ||
824 | |||
825 | if (lsr & UART_LSR_FE) | ||
826 | dev_err(&priv->pdev->dev, "Framing Error\n"); | ||
827 | |||
828 | if (lsr & UART_LSR_PE) | ||
829 | dev_err(&priv->pdev->dev, "Parity Error\n"); | ||
830 | |||
831 | if (lsr & UART_LSR_OE) | ||
832 | dev_err(&priv->pdev->dev, "Overrun Error\n"); | ||
833 | } | ||
834 | |||
835 | static irqreturn_t pch_uart_interrupt(int irq, void *dev_id) | ||
836 | { | ||
837 | struct eg20t_port *priv = dev_id; | ||
838 | unsigned int handled; | ||
839 | u8 lsr; | ||
840 | int ret = 0; | ||
841 | unsigned int iid; | ||
842 | unsigned long flags; | ||
843 | |||
844 | spin_lock_irqsave(&priv->port.lock, flags); | ||
845 | handled = 0; | ||
846 | while ((iid = pch_uart_hal_get_iid(priv)) > 1) { | ||
847 | switch (iid) { | ||
848 | case PCH_UART_IID_RLS: /* Receiver Line Status */ | ||
849 | lsr = pch_uart_hal_get_line_status(priv); | ||
850 | if (lsr & (PCH_UART_LSR_ERR | UART_LSR_FE | | ||
851 | UART_LSR_PE | UART_LSR_OE)) { | ||
852 | pch_uart_err_ir(priv, lsr); | ||
853 | ret = PCH_UART_HANDLED_RX_ERR_INT; | ||
854 | } | ||
855 | break; | ||
856 | case PCH_UART_IID_RDR: /* Received Data Ready */ | ||
857 | if (priv->use_dma) | ||
858 | ret = dma_handle_rx(priv); | ||
859 | else | ||
860 | ret = handle_rx(priv); | ||
861 | break; | ||
862 | case PCH_UART_IID_RDR_TO: /* Received Data Ready | ||
863 | (FIFO Timeout) */ | ||
864 | ret = handle_rx_to(priv); | ||
865 | break; | ||
866 | case PCH_UART_IID_THRE: /* Transmitter Holding Register | ||
867 | Empty */ | ||
868 | if (priv->use_dma) | ||
869 | ret = dma_handle_tx(priv); | ||
870 | else | ||
871 | ret = handle_tx(priv); | ||
872 | break; | ||
873 | case PCH_UART_IID_MS: /* Modem Status */ | ||
874 | ret = PCH_UART_HANDLED_MS_INT; | ||
875 | break; | ||
876 | default: /* Never junp to this label */ | ||
877 | pr_err("%s:iid=%d (%lu)\n", __func__, iid, jiffies); | ||
878 | ret = -1; | ||
879 | break; | ||
880 | } | ||
881 | handled |= (unsigned int)ret; | ||
882 | } | ||
883 | if (handled == 0 && iid <= 1) { | ||
884 | if (priv->int_dis_flag) | ||
885 | priv->int_dis_flag = 0; | ||
886 | } | ||
887 | |||
888 | spin_unlock_irqrestore(&priv->port.lock, flags); | ||
889 | return IRQ_RETVAL(handled); | ||
890 | } | ||
891 | |||
892 | /* This function tests whether the transmitter fifo and shifter for the port | ||
893 | described by 'port' is empty. */ | ||
894 | static unsigned int pch_uart_tx_empty(struct uart_port *port) | ||
895 | { | ||
896 | struct eg20t_port *priv; | ||
897 | int ret; | ||
898 | priv = container_of(port, struct eg20t_port, port); | ||
899 | if (priv->tx_empty) | ||
900 | ret = TIOCSER_TEMT; | ||
901 | else | ||
902 | ret = 0; | ||
903 | |||
904 | return ret; | ||
905 | } | ||
906 | |||
907 | /* Returns the current state of modem control inputs. */ | ||
908 | static unsigned int pch_uart_get_mctrl(struct uart_port *port) | ||
909 | { | ||
910 | struct eg20t_port *priv; | ||
911 | u8 modem; | ||
912 | unsigned int ret = 0; | ||
913 | |||
914 | priv = container_of(port, struct eg20t_port, port); | ||
915 | modem = pch_uart_hal_get_modem(priv); | ||
916 | |||
917 | if (modem & UART_MSR_DCD) | ||
918 | ret |= TIOCM_CAR; | ||
919 | |||
920 | if (modem & UART_MSR_RI) | ||
921 | ret |= TIOCM_RNG; | ||
922 | |||
923 | if (modem & UART_MSR_DSR) | ||
924 | ret |= TIOCM_DSR; | ||
925 | |||
926 | if (modem & UART_MSR_CTS) | ||
927 | ret |= TIOCM_CTS; | ||
928 | |||
929 | return ret; | ||
930 | } | ||
931 | |||
932 | static void pch_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
933 | { | ||
934 | u32 mcr = 0; | ||
935 | unsigned int dat; | ||
936 | struct eg20t_port *priv = container_of(port, struct eg20t_port, port); | ||
937 | |||
938 | if (mctrl & TIOCM_DTR) | ||
939 | mcr |= UART_MCR_DTR; | ||
940 | if (mctrl & TIOCM_RTS) | ||
941 | mcr |= UART_MCR_RTS; | ||
942 | if (mctrl & TIOCM_LOOP) | ||
943 | mcr |= UART_MCR_LOOP; | ||
944 | |||
945 | if (mctrl) { | ||
946 | dat = pch_uart_get_mctrl(port); | ||
947 | dat |= mcr; | ||
948 | iowrite8(dat, priv->membase + UART_MCR); | ||
949 | } | ||
950 | } | ||
951 | |||
952 | static void pch_uart_stop_tx(struct uart_port *port) | ||
953 | { | ||
954 | struct eg20t_port *priv; | ||
955 | priv = container_of(port, struct eg20t_port, port); | ||
956 | priv->start_tx = 0; | ||
957 | priv->tx_dma_use = 0; | ||
958 | } | ||
959 | |||
960 | static void pch_uart_start_tx(struct uart_port *port) | ||
961 | { | ||
962 | struct eg20t_port *priv; | ||
963 | |||
964 | priv = container_of(port, struct eg20t_port, port); | ||
965 | |||
966 | if (priv->use_dma) | ||
967 | if (priv->tx_dma_use) | ||
968 | return; | ||
969 | |||
970 | priv->start_tx = 1; | ||
971 | pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_TX_INT); | ||
972 | } | ||
973 | |||
974 | static void pch_uart_stop_rx(struct uart_port *port) | ||
975 | { | ||
976 | struct eg20t_port *priv; | ||
977 | priv = container_of(port, struct eg20t_port, port); | ||
978 | priv->start_rx = 0; | ||
979 | pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_RX_INT); | ||
980 | priv->int_dis_flag = 1; | ||
981 | } | ||
982 | |||
983 | /* Enable the modem status interrupts. */ | ||
984 | static void pch_uart_enable_ms(struct uart_port *port) | ||
985 | { | ||
986 | struct eg20t_port *priv; | ||
987 | priv = container_of(port, struct eg20t_port, port); | ||
988 | pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_MS_INT); | ||
989 | } | ||
990 | |||
991 | /* Control the transmission of a break signal. */ | ||
992 | static void pch_uart_break_ctl(struct uart_port *port, int ctl) | ||
993 | { | ||
994 | struct eg20t_port *priv; | ||
995 | unsigned long flags; | ||
996 | |||
997 | priv = container_of(port, struct eg20t_port, port); | ||
998 | spin_lock_irqsave(&port->lock, flags); | ||
999 | pch_uart_hal_set_break(priv, ctl); | ||
1000 | spin_unlock_irqrestore(&port->lock, flags); | ||
1001 | } | ||
1002 | |||
1003 | /* Grab any interrupt resources and initialise any low level driver state. */ | ||
1004 | static int pch_uart_startup(struct uart_port *port) | ||
1005 | { | ||
1006 | struct eg20t_port *priv; | ||
1007 | int ret; | ||
1008 | int fifo_size; | ||
1009 | int trigger_level; | ||
1010 | |||
1011 | priv = container_of(port, struct eg20t_port, port); | ||
1012 | priv->tx_empty = 1; | ||
1013 | port->uartclk = priv->base_baud; | ||
1014 | pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_ALL_INT); | ||
1015 | ret = pch_uart_hal_set_line(priv, default_baud, | ||
1016 | PCH_UART_HAL_PARITY_NONE, PCH_UART_HAL_8BIT, | ||
1017 | PCH_UART_HAL_STB1); | ||
1018 | if (ret) | ||
1019 | return ret; | ||
1020 | |||
1021 | switch (priv->fifo_size) { | ||
1022 | case 256: | ||
1023 | fifo_size = PCH_UART_HAL_FIFO256; | ||
1024 | break; | ||
1025 | case 64: | ||
1026 | fifo_size = PCH_UART_HAL_FIFO64; | ||
1027 | break; | ||
1028 | case 16: | ||
1029 | fifo_size = PCH_UART_HAL_FIFO16; | ||
1030 | case 1: | ||
1031 | default: | ||
1032 | fifo_size = PCH_UART_HAL_FIFO_DIS; | ||
1033 | break; | ||
1034 | } | ||
1035 | |||
1036 | switch (priv->trigger) { | ||
1037 | case PCH_UART_HAL_TRIGGER1: | ||
1038 | trigger_level = 1; | ||
1039 | break; | ||
1040 | case PCH_UART_HAL_TRIGGER_L: | ||
1041 | trigger_level = priv->fifo_size / 4; | ||
1042 | break; | ||
1043 | case PCH_UART_HAL_TRIGGER_M: | ||
1044 | trigger_level = priv->fifo_size / 2; | ||
1045 | break; | ||
1046 | case PCH_UART_HAL_TRIGGER_H: | ||
1047 | default: | ||
1048 | trigger_level = priv->fifo_size - (priv->fifo_size / 8); | ||
1049 | break; | ||
1050 | } | ||
1051 | |||
1052 | priv->trigger_level = trigger_level; | ||
1053 | ret = pch_uart_hal_set_fifo(priv, PCH_UART_HAL_DMA_MODE0, | ||
1054 | fifo_size, priv->trigger); | ||
1055 | if (ret < 0) | ||
1056 | return ret; | ||
1057 | |||
1058 | ret = request_irq(priv->port.irq, pch_uart_interrupt, IRQF_SHARED, | ||
1059 | KBUILD_MODNAME, priv); | ||
1060 | if (ret < 0) | ||
1061 | return ret; | ||
1062 | |||
1063 | if (priv->use_dma) | ||
1064 | pch_request_dma(port); | ||
1065 | |||
1066 | priv->start_rx = 1; | ||
1067 | pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_RX_INT); | ||
1068 | uart_update_timeout(port, CS8, default_baud); | ||
1069 | |||
1070 | return 0; | ||
1071 | } | ||
1072 | |||
1073 | static void pch_uart_shutdown(struct uart_port *port) | ||
1074 | { | ||
1075 | struct eg20t_port *priv; | ||
1076 | int ret; | ||
1077 | |||
1078 | priv = container_of(port, struct eg20t_port, port); | ||
1079 | pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_ALL_INT); | ||
1080 | pch_uart_hal_fifo_reset(priv, PCH_UART_HAL_CLR_ALL_FIFO); | ||
1081 | ret = pch_uart_hal_set_fifo(priv, PCH_UART_HAL_DMA_MODE0, | ||
1082 | PCH_UART_HAL_FIFO_DIS, PCH_UART_HAL_TRIGGER1); | ||
1083 | if (ret) | ||
1084 | pr_err("pch_uart_hal_set_fifo Failed(ret=%d)\n", ret); | ||
1085 | |||
1086 | if (priv->use_dma_flag) | ||
1087 | pch_free_dma(port); | ||
1088 | |||
1089 | free_irq(priv->port.irq, priv); | ||
1090 | } | ||
1091 | |||
1092 | /* Change the port parameters, including word length, parity, stop | ||
1093 | *bits. Update read_status_mask and ignore_status_mask to indicate | ||
1094 | *the types of events we are interested in receiving. */ | ||
1095 | static void pch_uart_set_termios(struct uart_port *port, | ||
1096 | struct ktermios *termios, struct ktermios *old) | ||
1097 | { | ||
1098 | int baud; | ||
1099 | int rtn; | ||
1100 | unsigned int parity, bits, stb; | ||
1101 | struct eg20t_port *priv; | ||
1102 | unsigned long flags; | ||
1103 | |||
1104 | priv = container_of(port, struct eg20t_port, port); | ||
1105 | switch (termios->c_cflag & CSIZE) { | ||
1106 | case CS5: | ||
1107 | bits = PCH_UART_HAL_5BIT; | ||
1108 | break; | ||
1109 | case CS6: | ||
1110 | bits = PCH_UART_HAL_6BIT; | ||
1111 | break; | ||
1112 | case CS7: | ||
1113 | bits = PCH_UART_HAL_7BIT; | ||
1114 | break; | ||
1115 | default: /* CS8 */ | ||
1116 | bits = PCH_UART_HAL_8BIT; | ||
1117 | break; | ||
1118 | } | ||
1119 | if (termios->c_cflag & CSTOPB) | ||
1120 | stb = PCH_UART_HAL_STB2; | ||
1121 | else | ||
1122 | stb = PCH_UART_HAL_STB1; | ||
1123 | |||
1124 | if (termios->c_cflag & PARENB) { | ||
1125 | if (!(termios->c_cflag & PARODD)) | ||
1126 | parity = PCH_UART_HAL_PARITY_ODD; | ||
1127 | else | ||
1128 | parity = PCH_UART_HAL_PARITY_EVEN; | ||
1129 | |||
1130 | } else { | ||
1131 | parity = PCH_UART_HAL_PARITY_NONE; | ||
1132 | } | ||
1133 | termios->c_cflag &= ~CMSPAR; /* Mark/Space parity is not supported */ | ||
1134 | |||
1135 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); | ||
1136 | |||
1137 | spin_lock_irqsave(&port->lock, flags); | ||
1138 | |||
1139 | uart_update_timeout(port, termios->c_cflag, baud); | ||
1140 | rtn = pch_uart_hal_set_line(priv, baud, parity, bits, stb); | ||
1141 | if (rtn) | ||
1142 | goto out; | ||
1143 | |||
1144 | /* Don't rewrite B0 */ | ||
1145 | if (tty_termios_baud_rate(termios)) | ||
1146 | tty_termios_encode_baud_rate(termios, baud, baud); | ||
1147 | |||
1148 | out: | ||
1149 | spin_unlock_irqrestore(&port->lock, flags); | ||
1150 | } | ||
1151 | |||
1152 | static const char *pch_uart_type(struct uart_port *port) | ||
1153 | { | ||
1154 | return KBUILD_MODNAME; | ||
1155 | } | ||
1156 | |||
1157 | static void pch_uart_release_port(struct uart_port *port) | ||
1158 | { | ||
1159 | struct eg20t_port *priv; | ||
1160 | |||
1161 | priv = container_of(port, struct eg20t_port, port); | ||
1162 | pci_iounmap(priv->pdev, priv->membase); | ||
1163 | pci_release_regions(priv->pdev); | ||
1164 | } | ||
1165 | |||
1166 | static int pch_uart_request_port(struct uart_port *port) | ||
1167 | { | ||
1168 | struct eg20t_port *priv; | ||
1169 | int ret; | ||
1170 | void __iomem *membase; | ||
1171 | |||
1172 | priv = container_of(port, struct eg20t_port, port); | ||
1173 | ret = pci_request_regions(priv->pdev, KBUILD_MODNAME); | ||
1174 | if (ret < 0) | ||
1175 | return -EBUSY; | ||
1176 | |||
1177 | membase = pci_iomap(priv->pdev, 1, 0); | ||
1178 | if (!membase) { | ||
1179 | pci_release_regions(priv->pdev); | ||
1180 | return -EBUSY; | ||
1181 | } | ||
1182 | priv->membase = port->membase = membase; | ||
1183 | |||
1184 | return 0; | ||
1185 | } | ||
1186 | |||
1187 | static void pch_uart_config_port(struct uart_port *port, int type) | ||
1188 | { | ||
1189 | struct eg20t_port *priv; | ||
1190 | |||
1191 | priv = container_of(port, struct eg20t_port, port); | ||
1192 | if (type & UART_CONFIG_TYPE) { | ||
1193 | port->type = priv->port_type; | ||
1194 | pch_uart_request_port(port); | ||
1195 | } | ||
1196 | } | ||
1197 | |||
1198 | static int pch_uart_verify_port(struct uart_port *port, | ||
1199 | struct serial_struct *serinfo) | ||
1200 | { | ||
1201 | struct eg20t_port *priv; | ||
1202 | |||
1203 | priv = container_of(port, struct eg20t_port, port); | ||
1204 | if (serinfo->flags & UPF_LOW_LATENCY) { | ||
1205 | pr_info("PCH UART : Use PIO Mode (without DMA)\n"); | ||
1206 | priv->use_dma = 0; | ||
1207 | serinfo->flags &= ~UPF_LOW_LATENCY; | ||
1208 | } else { | ||
1209 | #ifndef CONFIG_PCH_DMA | ||
1210 | pr_err("%s : PCH DMA is not Loaded.\n", __func__); | ||
1211 | return -EOPNOTSUPP; | ||
1212 | #endif | ||
1213 | priv->use_dma = 1; | ||
1214 | priv->use_dma_flag = 1; | ||
1215 | pr_info("PCH UART : Use DMA Mode\n"); | ||
1216 | } | ||
1217 | |||
1218 | return 0; | ||
1219 | } | ||
1220 | |||
1221 | static struct uart_ops pch_uart_ops = { | ||
1222 | .tx_empty = pch_uart_tx_empty, | ||
1223 | .set_mctrl = pch_uart_set_mctrl, | ||
1224 | .get_mctrl = pch_uart_get_mctrl, | ||
1225 | .stop_tx = pch_uart_stop_tx, | ||
1226 | .start_tx = pch_uart_start_tx, | ||
1227 | .stop_rx = pch_uart_stop_rx, | ||
1228 | .enable_ms = pch_uart_enable_ms, | ||
1229 | .break_ctl = pch_uart_break_ctl, | ||
1230 | .startup = pch_uart_startup, | ||
1231 | .shutdown = pch_uart_shutdown, | ||
1232 | .set_termios = pch_uart_set_termios, | ||
1233 | /* .pm = pch_uart_pm, Not supported yet */ | ||
1234 | /* .set_wake = pch_uart_set_wake, Not supported yet */ | ||
1235 | .type = pch_uart_type, | ||
1236 | .release_port = pch_uart_release_port, | ||
1237 | .request_port = pch_uart_request_port, | ||
1238 | .config_port = pch_uart_config_port, | ||
1239 | .verify_port = pch_uart_verify_port | ||
1240 | }; | ||
1241 | |||
1242 | static struct uart_driver pch_uart_driver = { | ||
1243 | .owner = THIS_MODULE, | ||
1244 | .driver_name = KBUILD_MODNAME, | ||
1245 | .dev_name = PCH_UART_DRIVER_DEVICE, | ||
1246 | .major = 0, | ||
1247 | .minor = 0, | ||
1248 | .nr = PCH_UART_NR, | ||
1249 | }; | ||
1250 | |||
1251 | static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, | ||
1252 | int port_type) | ||
1253 | { | ||
1254 | struct eg20t_port *priv; | ||
1255 | int ret; | ||
1256 | unsigned int iobase; | ||
1257 | unsigned int mapbase; | ||
1258 | unsigned char *rxbuf; | ||
1259 | int fifosize, base_baud; | ||
1260 | static int num; | ||
1261 | |||
1262 | priv = kzalloc(sizeof(struct eg20t_port), GFP_KERNEL); | ||
1263 | if (priv == NULL) | ||
1264 | goto init_port_alloc_err; | ||
1265 | |||
1266 | rxbuf = (unsigned char *)__get_free_page(GFP_KERNEL); | ||
1267 | if (!rxbuf) | ||
1268 | goto init_port_free_txbuf; | ||
1269 | |||
1270 | switch (port_type) { | ||
1271 | case PORT_UNKNOWN: | ||
1272 | fifosize = 256; /* UART0 */ | ||
1273 | base_baud = 1843200; /* 1.8432MHz */ | ||
1274 | break; | ||
1275 | case PORT_8250: | ||
1276 | fifosize = 64; /* UART1~3 */ | ||
1277 | base_baud = 1843200; /* 1.8432MHz */ | ||
1278 | break; | ||
1279 | default: | ||
1280 | dev_err(&pdev->dev, "Invalid Port Type(=%d)\n", port_type); | ||
1281 | goto init_port_hal_free; | ||
1282 | } | ||
1283 | |||
1284 | iobase = pci_resource_start(pdev, 0); | ||
1285 | mapbase = pci_resource_start(pdev, 1); | ||
1286 | priv->mapbase = mapbase; | ||
1287 | priv->iobase = iobase; | ||
1288 | priv->pdev = pdev; | ||
1289 | priv->tx_empty = 1; | ||
1290 | priv->rxbuf.buf = rxbuf; | ||
1291 | priv->rxbuf.size = PAGE_SIZE; | ||
1292 | |||
1293 | priv->fifo_size = fifosize; | ||
1294 | priv->base_baud = base_baud; | ||
1295 | priv->port_type = PORT_MAX_8250 + port_type + 1; | ||
1296 | priv->port.dev = &pdev->dev; | ||
1297 | priv->port.iobase = iobase; | ||
1298 | priv->port.membase = NULL; | ||
1299 | priv->port.mapbase = mapbase; | ||
1300 | priv->port.irq = pdev->irq; | ||
1301 | priv->port.iotype = UPIO_PORT; | ||
1302 | priv->port.ops = &pch_uart_ops; | ||
1303 | priv->port.flags = UPF_BOOT_AUTOCONF; | ||
1304 | priv->port.fifosize = fifosize; | ||
1305 | priv->port.line = num++; | ||
1306 | priv->trigger = PCH_UART_HAL_TRIGGER_M; | ||
1307 | |||
1308 | pci_set_drvdata(pdev, priv); | ||
1309 | pch_uart_hal_request(pdev, fifosize, base_baud); | ||
1310 | ret = uart_add_one_port(&pch_uart_driver, &priv->port); | ||
1311 | if (ret < 0) | ||
1312 | goto init_port_hal_free; | ||
1313 | |||
1314 | return priv; | ||
1315 | |||
1316 | init_port_hal_free: | ||
1317 | free_page((unsigned long)rxbuf); | ||
1318 | init_port_free_txbuf: | ||
1319 | kfree(priv); | ||
1320 | init_port_alloc_err: | ||
1321 | |||
1322 | return NULL; | ||
1323 | } | ||
1324 | |||
1325 | static void pch_uart_exit_port(struct eg20t_port *priv) | ||
1326 | { | ||
1327 | uart_remove_one_port(&pch_uart_driver, &priv->port); | ||
1328 | pci_set_drvdata(priv->pdev, NULL); | ||
1329 | free_page((unsigned long)priv->rxbuf.buf); | ||
1330 | } | ||
1331 | |||
1332 | static void pch_uart_pci_remove(struct pci_dev *pdev) | ||
1333 | { | ||
1334 | struct eg20t_port *priv; | ||
1335 | |||
1336 | priv = (struct eg20t_port *)pci_get_drvdata(pdev); | ||
1337 | pch_uart_exit_port(priv); | ||
1338 | pci_disable_device(pdev); | ||
1339 | kfree(priv); | ||
1340 | return; | ||
1341 | } | ||
1342 | #ifdef CONFIG_PM | ||
1343 | static int pch_uart_pci_suspend(struct pci_dev *pdev, pm_message_t state) | ||
1344 | { | ||
1345 | struct eg20t_port *priv = pci_get_drvdata(pdev); | ||
1346 | |||
1347 | uart_suspend_port(&pch_uart_driver, &priv->port); | ||
1348 | |||
1349 | pci_save_state(pdev); | ||
1350 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
1351 | return 0; | ||
1352 | } | ||
1353 | |||
1354 | static int pch_uart_pci_resume(struct pci_dev *pdev) | ||
1355 | { | ||
1356 | struct eg20t_port *priv = pci_get_drvdata(pdev); | ||
1357 | int ret; | ||
1358 | |||
1359 | pci_set_power_state(pdev, PCI_D0); | ||
1360 | pci_restore_state(pdev); | ||
1361 | |||
1362 | ret = pci_enable_device(pdev); | ||
1363 | if (ret) { | ||
1364 | dev_err(&pdev->dev, | ||
1365 | "%s-pci_enable_device failed(ret=%d) ", __func__, ret); | ||
1366 | return ret; | ||
1367 | } | ||
1368 | |||
1369 | uart_resume_port(&pch_uart_driver, &priv->port); | ||
1370 | |||
1371 | return 0; | ||
1372 | } | ||
1373 | #else | ||
1374 | #define pch_uart_pci_suspend NULL | ||
1375 | #define pch_uart_pci_resume NULL | ||
1376 | #endif | ||
1377 | |||
1378 | static DEFINE_PCI_DEVICE_TABLE(pch_uart_pci_id) = { | ||
1379 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8811), | ||
1380 | .driver_data = PCH_UART_8LINE}, | ||
1381 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8812), | ||
1382 | .driver_data = PCH_UART_2LINE}, | ||
1383 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8813), | ||
1384 | .driver_data = PCH_UART_2LINE}, | ||
1385 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8814), | ||
1386 | .driver_data = PCH_UART_2LINE}, | ||
1387 | {0,}, | ||
1388 | }; | ||
1389 | |||
1390 | static int __devinit pch_uart_pci_probe(struct pci_dev *pdev, | ||
1391 | const struct pci_device_id *id) | ||
1392 | { | ||
1393 | int ret; | ||
1394 | struct eg20t_port *priv; | ||
1395 | |||
1396 | ret = pci_enable_device(pdev); | ||
1397 | if (ret < 0) | ||
1398 | goto probe_error; | ||
1399 | |||
1400 | priv = pch_uart_init_port(pdev, id->driver_data); | ||
1401 | if (!priv) { | ||
1402 | ret = -EBUSY; | ||
1403 | goto probe_disable_device; | ||
1404 | } | ||
1405 | pci_set_drvdata(pdev, priv); | ||
1406 | |||
1407 | return ret; | ||
1408 | |||
1409 | probe_disable_device: | ||
1410 | pci_disable_device(pdev); | ||
1411 | probe_error: | ||
1412 | return ret; | ||
1413 | } | ||
1414 | |||
1415 | static struct pci_driver pch_uart_pci_driver = { | ||
1416 | .name = "pch_uart", | ||
1417 | .id_table = pch_uart_pci_id, | ||
1418 | .probe = pch_uart_pci_probe, | ||
1419 | .remove = __devexit_p(pch_uart_pci_remove), | ||
1420 | .suspend = pch_uart_pci_suspend, | ||
1421 | .resume = pch_uart_pci_resume, | ||
1422 | }; | ||
1423 | |||
1424 | static int __init pch_uart_module_init(void) | ||
1425 | { | ||
1426 | int ret; | ||
1427 | |||
1428 | /* register as UART driver */ | ||
1429 | ret = uart_register_driver(&pch_uart_driver); | ||
1430 | if (ret < 0) | ||
1431 | return ret; | ||
1432 | |||
1433 | /* register as PCI driver */ | ||
1434 | ret = pci_register_driver(&pch_uart_pci_driver); | ||
1435 | if (ret < 0) | ||
1436 | uart_unregister_driver(&pch_uart_driver); | ||
1437 | |||
1438 | return ret; | ||
1439 | } | ||
1440 | module_init(pch_uart_module_init); | ||
1441 | |||
1442 | static void __exit pch_uart_module_exit(void) | ||
1443 | { | ||
1444 | pci_unregister_driver(&pch_uart_pci_driver); | ||
1445 | uart_unregister_driver(&pch_uart_driver); | ||
1446 | } | ||
1447 | module_exit(pch_uart_module_exit); | ||
1448 | |||
1449 | MODULE_LICENSE("GPL v2"); | ||
1450 | MODULE_DESCRIPTION("Intel EG20T PCH UART PCI Driver"); | ||
1451 | module_param(default_baud, uint, S_IRUGO); | ||
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index 9c1243fbd512..5b9cde79e4ea 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c | |||
@@ -54,7 +54,6 @@ | |||
54 | #include <linux/delay.h> | 54 | #include <linux/delay.h> |
55 | #include <linux/init.h> | 55 | #include <linux/init.h> |
56 | #include <linux/console.h> | 56 | #include <linux/console.h> |
57 | #include <linux/slab.h> | ||
58 | #include <linux/adb.h> | 57 | #include <linux/adb.h> |
59 | #include <linux/pmu.h> | 58 | #include <linux/pmu.h> |
60 | #include <linux/bitops.h> | 59 | #include <linux/bitops.h> |
@@ -63,11 +62,17 @@ | |||
63 | #include <asm/sections.h> | 62 | #include <asm/sections.h> |
64 | #include <asm/io.h> | 63 | #include <asm/io.h> |
65 | #include <asm/irq.h> | 64 | #include <asm/irq.h> |
65 | |||
66 | #ifdef CONFIG_PPC_PMAC | ||
66 | #include <asm/prom.h> | 67 | #include <asm/prom.h> |
67 | #include <asm/machdep.h> | 68 | #include <asm/machdep.h> |
68 | #include <asm/pmac_feature.h> | 69 | #include <asm/pmac_feature.h> |
69 | #include <asm/dbdma.h> | 70 | #include <asm/dbdma.h> |
70 | #include <asm/macio.h> | 71 | #include <asm/macio.h> |
72 | #else | ||
73 | #include <linux/platform_device.h> | ||
74 | #define of_machine_is_compatible(x) (0) | ||
75 | #endif | ||
71 | 76 | ||
72 | #if defined (CONFIG_SERIAL_PMACZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | 77 | #if defined (CONFIG_SERIAL_PMACZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) |
73 | #define SUPPORT_SYSRQ | 78 | #define SUPPORT_SYSRQ |
@@ -83,11 +88,9 @@ | |||
83 | 88 | ||
84 | static char version[] __initdata = "pmac_zilog: 0.6 (Benjamin Herrenschmidt <benh@kernel.crashing.org>)"; | 89 | static char version[] __initdata = "pmac_zilog: 0.6 (Benjamin Herrenschmidt <benh@kernel.crashing.org>)"; |
85 | MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>"); | 90 | MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>"); |
86 | MODULE_DESCRIPTION("Driver for the PowerMac serial ports."); | 91 | MODULE_DESCRIPTION("Driver for the Mac and PowerMac serial ports."); |
87 | MODULE_LICENSE("GPL"); | 92 | MODULE_LICENSE("GPL"); |
88 | 93 | ||
89 | #define PWRDBG(fmt, arg...) printk(KERN_DEBUG fmt , ## arg) | ||
90 | |||
91 | #ifdef CONFIG_SERIAL_PMACZILOG_TTYS | 94 | #ifdef CONFIG_SERIAL_PMACZILOG_TTYS |
92 | #define PMACZILOG_MAJOR TTY_MAJOR | 95 | #define PMACZILOG_MAJOR TTY_MAJOR |
93 | #define PMACZILOG_MINOR 64 | 96 | #define PMACZILOG_MINOR 64 |
@@ -153,8 +156,8 @@ static void pmz_load_zsregs(struct uart_pmac_port *uap, u8 *regs) | |||
153 | write_zsreg(uap, R10, regs[R10]); | 156 | write_zsreg(uap, R10, regs[R10]); |
154 | 157 | ||
155 | /* Set TX/RX controls sans the enable bits. */ | 158 | /* Set TX/RX controls sans the enable bits. */ |
156 | write_zsreg(uap, R3, regs[R3] & ~RxENABLE); | 159 | write_zsreg(uap, R3, regs[R3] & ~RxENABLE); |
157 | write_zsreg(uap, R5, regs[R5] & ~TxENABLE); | 160 | write_zsreg(uap, R5, regs[R5] & ~TxENABLE); |
158 | 161 | ||
159 | /* now set R7 "prime" on ESCC */ | 162 | /* now set R7 "prime" on ESCC */ |
160 | write_zsreg(uap, R15, regs[R15] | EN85C30); | 163 | write_zsreg(uap, R15, regs[R15] | EN85C30); |
@@ -205,7 +208,7 @@ static void pmz_load_zsregs(struct uart_pmac_port *uap, u8 *regs) | |||
205 | */ | 208 | */ |
206 | static void pmz_maybe_update_regs(struct uart_pmac_port *uap) | 209 | static void pmz_maybe_update_regs(struct uart_pmac_port *uap) |
207 | { | 210 | { |
208 | if (!ZS_REGS_HELD(uap)) { | 211 | if (!ZS_REGS_HELD(uap)) { |
209 | if (ZS_TX_ACTIVE(uap)) { | 212 | if (ZS_TX_ACTIVE(uap)) { |
210 | uap->flags |= PMACZILOG_FLAG_REGS_HELD; | 213 | uap->flags |= PMACZILOG_FLAG_REGS_HELD; |
211 | } else { | 214 | } else { |
@@ -242,12 +245,12 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap) | |||
242 | } | 245 | } |
243 | 246 | ||
244 | /* Sanity check, make sure the old bug is no longer happening */ | 247 | /* Sanity check, make sure the old bug is no longer happening */ |
245 | if (uap->port.info == NULL || uap->port.info->port.tty == NULL) { | 248 | if (uap->port.state == NULL || uap->port.state->port.tty == NULL) { |
246 | WARN_ON(1); | 249 | WARN_ON(1); |
247 | (void)read_zsdata(uap); | 250 | (void)read_zsdata(uap); |
248 | return NULL; | 251 | return NULL; |
249 | } | 252 | } |
250 | tty = uap->port.info->port.tty; | 253 | tty = uap->port.state->port.tty; |
251 | 254 | ||
252 | while (1) { | 255 | while (1) { |
253 | error = 0; | 256 | error = 0; |
@@ -281,7 +284,7 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap) | |||
281 | spin_lock(&uap->port.lock); | 284 | spin_lock(&uap->port.lock); |
282 | if (swallow) | 285 | if (swallow) |
283 | goto next_char; | 286 | goto next_char; |
284 | } | 287 | } |
285 | #endif /* CONFIG_MAGIC_SYSRQ && CONFIG_SERIAL_CORE_CONSOLE */ | 288 | #endif /* CONFIG_MAGIC_SYSRQ && CONFIG_SERIAL_CORE_CONSOLE */ |
286 | 289 | ||
287 | /* A real serial line, record the character and status. */ | 290 | /* A real serial line, record the character and status. */ |
@@ -317,7 +320,7 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap) | |||
317 | 320 | ||
318 | if (uap->port.ignore_status_mask == 0xff || | 321 | if (uap->port.ignore_status_mask == 0xff || |
319 | (r1 & uap->port.ignore_status_mask) == 0) { | 322 | (r1 & uap->port.ignore_status_mask) == 0) { |
320 | tty_insert_flip_char(tty, ch, flag); | 323 | tty_insert_flip_char(tty, ch, flag); |
321 | } | 324 | } |
322 | if (r1 & Rx_OVR) | 325 | if (r1 & Rx_OVR) |
323 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 326 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
@@ -341,7 +344,7 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap) | |||
341 | uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK); | 344 | uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK); |
342 | write_zsreg(uap, R1, uap->curregs[R1]); | 345 | write_zsreg(uap, R1, uap->curregs[R1]); |
343 | zssync(uap); | 346 | zssync(uap); |
344 | dev_err(&uap->dev->ofdev.dev, "pmz: rx irq flood !\n"); | 347 | pmz_error("pmz: rx irq flood !\n"); |
345 | return tty; | 348 | return tty; |
346 | } | 349 | } |
347 | 350 | ||
@@ -369,7 +372,7 @@ static void pmz_status_handle(struct uart_pmac_port *uap) | |||
369 | uart_handle_cts_change(&uap->port, | 372 | uart_handle_cts_change(&uap->port, |
370 | !(status & CTS)); | 373 | !(status & CTS)); |
371 | 374 | ||
372 | wake_up_interruptible(&uap->port.info->delta_msr_wait); | 375 | wake_up_interruptible(&uap->port.state->port.delta_msr_wait); |
373 | } | 376 | } |
374 | 377 | ||
375 | if (status & BRK_ABRT) | 378 | if (status & BRK_ABRT) |
@@ -411,6 +414,17 @@ static void pmz_transmit_chars(struct uart_pmac_port *uap) | |||
411 | goto ack_tx_int; | 414 | goto ack_tx_int; |
412 | } | 415 | } |
413 | 416 | ||
417 | /* Under some circumstances, we see interrupts reported for | ||
418 | * a closed channel. The interrupt mask in R1 is clear, but | ||
419 | * R3 still signals the interrupts and we see them when taking | ||
420 | * an interrupt for the other channel (this could be a qemu | ||
421 | * bug but since the ESCC doc doesn't specify precsiely whether | ||
422 | * R3 interrup status bits are masked by R1 interrupt enable | ||
423 | * bits, better safe than sorry). --BenH. | ||
424 | */ | ||
425 | if (!ZS_IS_OPEN(uap)) | ||
426 | goto ack_tx_int; | ||
427 | |||
414 | if (uap->port.x_char) { | 428 | if (uap->port.x_char) { |
415 | uap->flags |= PMACZILOG_FLAG_TX_ACTIVE; | 429 | uap->flags |= PMACZILOG_FLAG_TX_ACTIVE; |
416 | write_zsdata(uap, uap->port.x_char); | 430 | write_zsdata(uap, uap->port.x_char); |
@@ -420,9 +434,9 @@ static void pmz_transmit_chars(struct uart_pmac_port *uap) | |||
420 | return; | 434 | return; |
421 | } | 435 | } |
422 | 436 | ||
423 | if (uap->port.info == NULL) | 437 | if (uap->port.state == NULL) |
424 | goto ack_tx_int; | 438 | goto ack_tx_int; |
425 | xmit = &uap->port.info->xmit; | 439 | xmit = &uap->port.state->xmit; |
426 | if (uart_circ_empty(xmit)) { | 440 | if (uart_circ_empty(xmit)) { |
427 | uart_write_wakeup(&uap->port); | 441 | uart_write_wakeup(&uap->port); |
428 | goto ack_tx_int; | 442 | goto ack_tx_int; |
@@ -459,47 +473,47 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) | |||
459 | 473 | ||
460 | uap_a = pmz_get_port_A(uap); | 474 | uap_a = pmz_get_port_A(uap); |
461 | uap_b = uap_a->mate; | 475 | uap_b = uap_a->mate; |
462 | 476 | ||
463 | spin_lock(&uap_a->port.lock); | 477 | spin_lock(&uap_a->port.lock); |
464 | r3 = read_zsreg(uap_a, R3); | 478 | r3 = read_zsreg(uap_a, R3); |
465 | 479 | ||
466 | #ifdef DEBUG_HARD | 480 | #ifdef DEBUG_HARD |
467 | pmz_debug("irq, r3: %x\n", r3); | 481 | pmz_debug("irq, r3: %x\n", r3); |
468 | #endif | 482 | #endif |
469 | /* Channel A */ | 483 | /* Channel A */ |
470 | tty = NULL; | 484 | tty = NULL; |
471 | if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { | 485 | if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { |
472 | write_zsreg(uap_a, R0, RES_H_IUS); | 486 | write_zsreg(uap_a, R0, RES_H_IUS); |
473 | zssync(uap_a); | 487 | zssync(uap_a); |
474 | if (r3 & CHAEXT) | 488 | if (r3 & CHAEXT) |
475 | pmz_status_handle(uap_a); | 489 | pmz_status_handle(uap_a); |
476 | if (r3 & CHARxIP) | 490 | if (r3 & CHARxIP) |
477 | tty = pmz_receive_chars(uap_a); | 491 | tty = pmz_receive_chars(uap_a); |
478 | if (r3 & CHATxIP) | 492 | if (r3 & CHATxIP) |
479 | pmz_transmit_chars(uap_a); | 493 | pmz_transmit_chars(uap_a); |
480 | rc = IRQ_HANDLED; | 494 | rc = IRQ_HANDLED; |
481 | } | 495 | } |
482 | spin_unlock(&uap_a->port.lock); | 496 | spin_unlock(&uap_a->port.lock); |
483 | if (tty != NULL) | 497 | if (tty != NULL) |
484 | tty_flip_buffer_push(tty); | 498 | tty_flip_buffer_push(tty); |
485 | 499 | ||
486 | if (uap_b->node == NULL) | 500 | if (uap_b->node == NULL) |
487 | goto out; | 501 | goto out; |
488 | 502 | ||
489 | spin_lock(&uap_b->port.lock); | 503 | spin_lock(&uap_b->port.lock); |
490 | tty = NULL; | 504 | tty = NULL; |
491 | if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { | 505 | if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { |
492 | write_zsreg(uap_b, R0, RES_H_IUS); | 506 | write_zsreg(uap_b, R0, RES_H_IUS); |
493 | zssync(uap_b); | 507 | zssync(uap_b); |
494 | if (r3 & CHBEXT) | 508 | if (r3 & CHBEXT) |
495 | pmz_status_handle(uap_b); | 509 | pmz_status_handle(uap_b); |
496 | if (r3 & CHBRxIP) | 510 | if (r3 & CHBRxIP) |
497 | tty = pmz_receive_chars(uap_b); | 511 | tty = pmz_receive_chars(uap_b); |
498 | if (r3 & CHBTxIP) | 512 | if (r3 & CHBTxIP) |
499 | pmz_transmit_chars(uap_b); | 513 | pmz_transmit_chars(uap_b); |
500 | rc = IRQ_HANDLED; | 514 | rc = IRQ_HANDLED; |
501 | } | 515 | } |
502 | spin_unlock(&uap_b->port.lock); | 516 | spin_unlock(&uap_b->port.lock); |
503 | if (tty != NULL) | 517 | if (tty != NULL) |
504 | tty_flip_buffer_push(tty); | 518 | tty_flip_buffer_push(tty); |
505 | 519 | ||
@@ -655,7 +669,7 @@ static void pmz_start_tx(struct uart_port *port) | |||
655 | port->icount.tx++; | 669 | port->icount.tx++; |
656 | port->x_char = 0; | 670 | port->x_char = 0; |
657 | } else { | 671 | } else { |
658 | struct circ_buf *xmit = &port->info->xmit; | 672 | struct circ_buf *xmit = &port->state->xmit; |
659 | 673 | ||
660 | write_zsdata(uap, xmit->buf[xmit->tail]); | 674 | write_zsdata(uap, xmit->buf[xmit->tail]); |
661 | zssync(uap); | 675 | zssync(uap); |
@@ -707,7 +721,7 @@ static void pmz_enable_ms(struct uart_port *port) | |||
707 | 721 | ||
708 | if (ZS_IS_ASLEEP(uap)) | 722 | if (ZS_IS_ASLEEP(uap)) |
709 | return; | 723 | return; |
710 | /* NOTE: Not subject to 'transmitter active' rule. */ | 724 | /* NOTE: Not subject to 'transmitter active' rule. */ |
711 | write_zsreg(uap, R15, uap->curregs[R15]); | 725 | write_zsreg(uap, R15, uap->curregs[R15]); |
712 | } | 726 | } |
713 | } | 727 | } |
@@ -737,15 +751,19 @@ static void pmz_break_ctl(struct uart_port *port, int break_state) | |||
737 | if (new_reg != uap->curregs[R5]) { | 751 | if (new_reg != uap->curregs[R5]) { |
738 | uap->curregs[R5] = new_reg; | 752 | uap->curregs[R5] = new_reg; |
739 | 753 | ||
740 | /* NOTE: Not subject to 'transmitter active' rule. */ | 754 | /* NOTE: Not subject to 'transmitter active' rule. */ |
741 | if (ZS_IS_ASLEEP(uap)) | 755 | if (ZS_IS_ASLEEP(uap)) { |
756 | spin_unlock_irqrestore(&port->lock, flags); | ||
742 | return; | 757 | return; |
758 | } | ||
743 | write_zsreg(uap, R5, uap->curregs[R5]); | 759 | write_zsreg(uap, R5, uap->curregs[R5]); |
744 | } | 760 | } |
745 | 761 | ||
746 | spin_unlock_irqrestore(&port->lock, flags); | 762 | spin_unlock_irqrestore(&port->lock, flags); |
747 | } | 763 | } |
748 | 764 | ||
765 | #ifdef CONFIG_PPC_PMAC | ||
766 | |||
749 | /* | 767 | /* |
750 | * Turn power on or off to the SCC and associated stuff | 768 | * Turn power on or off to the SCC and associated stuff |
751 | * (port drivers, modem, IR port, etc.) | 769 | * (port drivers, modem, IR port, etc.) |
@@ -781,6 +799,15 @@ static int pmz_set_scc_power(struct uart_pmac_port *uap, int state) | |||
781 | return delay; | 799 | return delay; |
782 | } | 800 | } |
783 | 801 | ||
802 | #else | ||
803 | |||
804 | static int pmz_set_scc_power(struct uart_pmac_port *uap, int state) | ||
805 | { | ||
806 | return 0; | ||
807 | } | ||
808 | |||
809 | #endif /* !CONFIG_PPC_PMAC */ | ||
810 | |||
784 | /* | 811 | /* |
785 | * FixZeroBug....Works around a bug in the SCC receving channel. | 812 | * FixZeroBug....Works around a bug in the SCC receving channel. |
786 | * Inspired from Darwin code, 15 Sept. 2000 -DanM | 813 | * Inspired from Darwin code, 15 Sept. 2000 -DanM |
@@ -897,7 +924,6 @@ static int __pmz_startup(struct uart_pmac_port *uap) | |||
897 | /* Remember status for DCD/CTS changes */ | 924 | /* Remember status for DCD/CTS changes */ |
898 | uap->prev_status = read_zsreg(uap, R0); | 925 | uap->prev_status = read_zsreg(uap, R0); |
899 | 926 | ||
900 | |||
901 | return pwr_delay; | 927 | return pwr_delay; |
902 | } | 928 | } |
903 | 929 | ||
@@ -944,9 +970,9 @@ static int pmz_startup(struct uart_port *port) | |||
944 | } | 970 | } |
945 | 971 | ||
946 | pmz_get_port_A(uap)->flags |= PMACZILOG_FLAG_IS_IRQ_ON; | 972 | pmz_get_port_A(uap)->flags |= PMACZILOG_FLAG_IS_IRQ_ON; |
947 | if (request_irq(uap->port.irq, pmz_interrupt, IRQF_SHARED, "PowerMac Zilog", uap)) { | 973 | if (request_irq(uap->port.irq, pmz_interrupt, IRQF_SHARED, |
948 | dev_err(&uap->dev->ofdev.dev, | 974 | "SCC", uap)) { |
949 | "Unable to register zs interrupt handler.\n"); | 975 | pmz_error("Unable to register zs interrupt handler.\n"); |
950 | pmz_set_scc_power(uap, 0); | 976 | pmz_set_scc_power(uap, 0); |
951 | mutex_unlock(&pmz_irq_mutex); | 977 | mutex_unlock(&pmz_irq_mutex); |
952 | return -ENXIO; | 978 | return -ENXIO; |
@@ -972,7 +998,7 @@ static int pmz_startup(struct uart_port *port) | |||
972 | if (!ZS_IS_EXTCLK(uap)) | 998 | if (!ZS_IS_EXTCLK(uap)) |
973 | uap->curregs[R1] |= EXT_INT_ENAB; | 999 | uap->curregs[R1] |= EXT_INT_ENAB; |
974 | write_zsreg(uap, R1, uap->curregs[R1]); | 1000 | write_zsreg(uap, R1, uap->curregs[R1]); |
975 | spin_unlock_irqrestore(&port->lock, flags); | 1001 | spin_unlock_irqrestore(&port->lock, flags); |
976 | 1002 | ||
977 | pmz_debug("pmz: startup() done.\n"); | 1003 | pmz_debug("pmz: startup() done.\n"); |
978 | 1004 | ||
@@ -992,7 +1018,7 @@ static void pmz_shutdown(struct uart_port *port) | |||
992 | mutex_lock(&pmz_irq_mutex); | 1018 | mutex_lock(&pmz_irq_mutex); |
993 | 1019 | ||
994 | /* Release interrupt handler */ | 1020 | /* Release interrupt handler */ |
995 | free_irq(uap->port.irq, uap); | 1021 | free_irq(uap->port.irq, uap); |
996 | 1022 | ||
997 | spin_lock_irqsave(&port->lock, flags); | 1023 | spin_lock_irqsave(&port->lock, flags); |
998 | 1024 | ||
@@ -1040,7 +1066,6 @@ static void pmz_convert_to_zs(struct uart_pmac_port *uap, unsigned int cflag, | |||
1040 | { | 1066 | { |
1041 | int brg; | 1067 | int brg; |
1042 | 1068 | ||
1043 | |||
1044 | /* Switch to external clocking for IrDA high clock rates. That | 1069 | /* Switch to external clocking for IrDA high clock rates. That |
1045 | * code could be re-used for Midi interfaces with different | 1070 | * code could be re-used for Midi interfaces with different |
1046 | * multipliers | 1071 | * multipliers |
@@ -1187,7 +1212,7 @@ static void pmz_irda_setup(struct uart_pmac_port *uap, unsigned long *baud) | |||
1187 | while ((read_zsreg(uap, R0) & Tx_BUF_EMP) == 0 | 1212 | while ((read_zsreg(uap, R0) & Tx_BUF_EMP) == 0 |
1188 | || (read_zsreg(uap, R1) & ALL_SNT) == 0) { | 1213 | || (read_zsreg(uap, R1) & ALL_SNT) == 0) { |
1189 | if (--t <= 0) { | 1214 | if (--t <= 0) { |
1190 | dev_err(&uap->dev->ofdev.dev, "transmitter didn't drain\n"); | 1215 | pmz_error("transmitter didn't drain\n"); |
1191 | return; | 1216 | return; |
1192 | } | 1217 | } |
1193 | udelay(10); | 1218 | udelay(10); |
@@ -1203,7 +1228,7 @@ static void pmz_irda_setup(struct uart_pmac_port *uap, unsigned long *baud) | |||
1203 | read_zsdata(uap); | 1228 | read_zsdata(uap); |
1204 | mdelay(10); | 1229 | mdelay(10); |
1205 | if (--t <= 0) { | 1230 | if (--t <= 0) { |
1206 | dev_err(&uap->dev->ofdev.dev, "receiver didn't drain\n"); | 1231 | pmz_error("receiver didn't drain\n"); |
1207 | return; | 1232 | return; |
1208 | } | 1233 | } |
1209 | } | 1234 | } |
@@ -1212,20 +1237,19 @@ static void pmz_irda_setup(struct uart_pmac_port *uap, unsigned long *baud) | |||
1212 | uap->curregs[R5] |= DTR; | 1237 | uap->curregs[R5] |= DTR; |
1213 | write_zsreg(uap, R5, uap->curregs[R5]); | 1238 | write_zsreg(uap, R5, uap->curregs[R5]); |
1214 | zssync(uap); | 1239 | zssync(uap); |
1215 | mdelay(1); | 1240 | mdelay(1); |
1216 | 1241 | ||
1217 | /* Switch SCC to 19200 */ | 1242 | /* Switch SCC to 19200 */ |
1218 | pmz_convert_to_zs(uap, CS8, 0, 19200); | 1243 | pmz_convert_to_zs(uap, CS8, 0, 19200); |
1219 | pmz_load_zsregs(uap, uap->curregs); | 1244 | pmz_load_zsregs(uap, uap->curregs); |
1220 | mdelay(1); | 1245 | mdelay(1); |
1221 | 1246 | ||
1222 | /* Write get_version command byte */ | 1247 | /* Write get_version command byte */ |
1223 | write_zsdata(uap, 1); | 1248 | write_zsdata(uap, 1); |
1224 | t = 5000; | 1249 | t = 5000; |
1225 | while ((read_zsreg(uap, R0) & Rx_CH_AV) == 0) { | 1250 | while ((read_zsreg(uap, R0) & Rx_CH_AV) == 0) { |
1226 | if (--t <= 0) { | 1251 | if (--t <= 0) { |
1227 | dev_err(&uap->dev->ofdev.dev, | 1252 | pmz_error("irda_setup timed out on get_version byte\n"); |
1228 | "irda_setup timed out on get_version byte\n"); | ||
1229 | goto out; | 1253 | goto out; |
1230 | } | 1254 | } |
1231 | udelay(10); | 1255 | udelay(10); |
@@ -1233,8 +1257,7 @@ static void pmz_irda_setup(struct uart_pmac_port *uap, unsigned long *baud) | |||
1233 | version = read_zsdata(uap); | 1257 | version = read_zsdata(uap); |
1234 | 1258 | ||
1235 | if (version < 4) { | 1259 | if (version < 4) { |
1236 | dev_info(&uap->dev->ofdev.dev, "IrDA: dongle version %d not supported\n", | 1260 | pmz_info("IrDA: dongle version %d not supported\n", version); |
1237 | version); | ||
1238 | goto out; | 1261 | goto out; |
1239 | } | 1262 | } |
1240 | 1263 | ||
@@ -1243,18 +1266,16 @@ static void pmz_irda_setup(struct uart_pmac_port *uap, unsigned long *baud) | |||
1243 | t = 5000; | 1266 | t = 5000; |
1244 | while ((read_zsreg(uap, R0) & Rx_CH_AV) == 0) { | 1267 | while ((read_zsreg(uap, R0) & Rx_CH_AV) == 0) { |
1245 | if (--t <= 0) { | 1268 | if (--t <= 0) { |
1246 | dev_err(&uap->dev->ofdev.dev, | 1269 | pmz_error("irda_setup timed out on speed mode byte\n"); |
1247 | "irda_setup timed out on speed mode byte\n"); | ||
1248 | goto out; | 1270 | goto out; |
1249 | } | 1271 | } |
1250 | udelay(10); | 1272 | udelay(10); |
1251 | } | 1273 | } |
1252 | t = read_zsdata(uap); | 1274 | t = read_zsdata(uap); |
1253 | if (t != cmdbyte) | 1275 | if (t != cmdbyte) |
1254 | dev_err(&uap->dev->ofdev.dev, | 1276 | pmz_error("irda_setup speed mode byte = %x (%x)\n", t, cmdbyte); |
1255 | "irda_setup speed mode byte = %x (%x)\n", t, cmdbyte); | ||
1256 | 1277 | ||
1257 | dev_info(&uap->dev->ofdev.dev, "IrDA setup for %ld bps, dongle version: %d\n", | 1278 | pmz_info("IrDA setup for %ld bps, dongle version: %d\n", |
1258 | *baud, version); | 1279 | *baud, version); |
1259 | 1280 | ||
1260 | (void)read_zsdata(uap); | 1281 | (void)read_zsdata(uap); |
@@ -1404,7 +1425,7 @@ static void pmz_poll_put_char(struct uart_port *port, unsigned char c) | |||
1404 | write_zsdata(uap, c); | 1425 | write_zsdata(uap, c); |
1405 | } | 1426 | } |
1406 | 1427 | ||
1407 | #endif | 1428 | #endif /* CONFIG_CONSOLE_POLL */ |
1408 | 1429 | ||
1409 | static struct uart_ops pmz_pops = { | 1430 | static struct uart_ops pmz_pops = { |
1410 | .tx_empty = pmz_tx_empty, | 1431 | .tx_empty = pmz_tx_empty, |
@@ -1429,6 +1450,8 @@ static struct uart_ops pmz_pops = { | |||
1429 | #endif | 1450 | #endif |
1430 | }; | 1451 | }; |
1431 | 1452 | ||
1453 | #ifdef CONFIG_PPC_PMAC | ||
1454 | |||
1432 | /* | 1455 | /* |
1433 | * Setup one port structure after probing, HW is down at this point, | 1456 | * Setup one port structure after probing, HW is down at this point, |
1434 | * Unlike sunzilog, we don't need to pre-init the spinlock as we don't | 1457 | * Unlike sunzilog, we don't need to pre-init the spinlock as we don't |
@@ -1452,7 +1475,7 @@ static int __init pmz_init_port(struct uart_pmac_port *uap) | |||
1452 | return -ENODEV; | 1475 | return -ENODEV; |
1453 | uap->port.mapbase = r_ports.start; | 1476 | uap->port.mapbase = r_ports.start; |
1454 | uap->port.membase = ioremap(uap->port.mapbase, 0x1000); | 1477 | uap->port.membase = ioremap(uap->port.mapbase, 0x1000); |
1455 | 1478 | ||
1456 | uap->control_reg = uap->port.membase; | 1479 | uap->control_reg = uap->port.membase; |
1457 | uap->data_reg = uap->control_reg + 0x10; | 1480 | uap->data_reg = uap->control_reg + 0x10; |
1458 | 1481 | ||
@@ -1579,7 +1602,7 @@ static void pmz_dispose_port(struct uart_pmac_port *uap) | |||
1579 | } | 1602 | } |
1580 | 1603 | ||
1581 | /* | 1604 | /* |
1582 | * Called upon match with an escc node in the devive-tree. | 1605 | * Called upon match with an escc node in the device-tree. |
1583 | */ | 1606 | */ |
1584 | static int pmz_attach(struct macio_dev *mdev, const struct of_device_id *match) | 1607 | static int pmz_attach(struct macio_dev *mdev, const struct of_device_id *match) |
1585 | { | 1608 | { |
@@ -1588,7 +1611,7 @@ static int pmz_attach(struct macio_dev *mdev, const struct of_device_id *match) | |||
1588 | /* Iterate the pmz_ports array to find a matching entry | 1611 | /* Iterate the pmz_ports array to find a matching entry |
1589 | */ | 1612 | */ |
1590 | for (i = 0; i < MAX_ZS_PORTS; i++) | 1613 | for (i = 0; i < MAX_ZS_PORTS; i++) |
1591 | if (pmz_ports[i].node == mdev->ofdev.node) { | 1614 | if (pmz_ports[i].node == mdev->ofdev.dev.of_node) { |
1592 | struct uart_pmac_port *uap = &pmz_ports[i]; | 1615 | struct uart_pmac_port *uap = &pmz_ports[i]; |
1593 | 1616 | ||
1594 | uap->dev = mdev; | 1617 | uap->dev = mdev; |
@@ -1645,7 +1668,7 @@ static int pmz_suspend(struct macio_dev *mdev, pm_message_t pm_state) | |||
1645 | state = pmz_uart_reg.state + uap->port.line; | 1668 | state = pmz_uart_reg.state + uap->port.line; |
1646 | 1669 | ||
1647 | mutex_lock(&pmz_irq_mutex); | 1670 | mutex_lock(&pmz_irq_mutex); |
1648 | mutex_lock(&state->mutex); | 1671 | mutex_lock(&state->port.mutex); |
1649 | 1672 | ||
1650 | spin_lock_irqsave(&uap->port.lock, flags); | 1673 | spin_lock_irqsave(&uap->port.lock, flags); |
1651 | 1674 | ||
@@ -1676,7 +1699,7 @@ static int pmz_suspend(struct macio_dev *mdev, pm_message_t pm_state) | |||
1676 | /* Shut the chip down */ | 1699 | /* Shut the chip down */ |
1677 | pmz_set_scc_power(uap, 0); | 1700 | pmz_set_scc_power(uap, 0); |
1678 | 1701 | ||
1679 | mutex_unlock(&state->mutex); | 1702 | mutex_unlock(&state->port.mutex); |
1680 | mutex_unlock(&pmz_irq_mutex); | 1703 | mutex_unlock(&pmz_irq_mutex); |
1681 | 1704 | ||
1682 | pmz_debug("suspend, switching complete\n"); | 1705 | pmz_debug("suspend, switching complete\n"); |
@@ -1705,7 +1728,7 @@ static int pmz_resume(struct macio_dev *mdev) | |||
1705 | state = pmz_uart_reg.state + uap->port.line; | 1728 | state = pmz_uart_reg.state + uap->port.line; |
1706 | 1729 | ||
1707 | mutex_lock(&pmz_irq_mutex); | 1730 | mutex_lock(&pmz_irq_mutex); |
1708 | mutex_lock(&state->mutex); | 1731 | mutex_lock(&state->port.mutex); |
1709 | 1732 | ||
1710 | spin_lock_irqsave(&uap->port.lock, flags); | 1733 | spin_lock_irqsave(&uap->port.lock, flags); |
1711 | if (!ZS_IS_OPEN(uap) && !ZS_IS_CONS(uap)) { | 1734 | if (!ZS_IS_OPEN(uap) && !ZS_IS_CONS(uap)) { |
@@ -1737,7 +1760,7 @@ static int pmz_resume(struct macio_dev *mdev) | |||
1737 | } | 1760 | } |
1738 | 1761 | ||
1739 | bail: | 1762 | bail: |
1740 | mutex_unlock(&state->mutex); | 1763 | mutex_unlock(&state->port.mutex); |
1741 | mutex_unlock(&pmz_irq_mutex); | 1764 | mutex_unlock(&pmz_irq_mutex); |
1742 | 1765 | ||
1743 | /* Right now, we deal with delay by blocking here, I'll be | 1766 | /* Right now, we deal with delay by blocking here, I'll be |
@@ -1801,7 +1824,7 @@ static int __init pmz_probe(void) | |||
1801 | pmz_ports[count].node = node_a; | 1824 | pmz_ports[count].node = node_a; |
1802 | pmz_ports[count+1].node = node_b; | 1825 | pmz_ports[count+1].node = node_b; |
1803 | pmz_ports[count].port.line = count; | 1826 | pmz_ports[count].port.line = count; |
1804 | pmz_ports[count+1].port.line = count+1; | 1827 | pmz_ports[count+1].port.line = count+1; |
1805 | 1828 | ||
1806 | /* | 1829 | /* |
1807 | * Setup the ports for real | 1830 | * Setup the ports for real |
@@ -1825,6 +1848,88 @@ next: | |||
1825 | return 0; | 1848 | return 0; |
1826 | } | 1849 | } |
1827 | 1850 | ||
1851 | #else | ||
1852 | |||
1853 | extern struct platform_device scc_a_pdev, scc_b_pdev; | ||
1854 | |||
1855 | static int __init pmz_init_port(struct uart_pmac_port *uap) | ||
1856 | { | ||
1857 | struct resource *r_ports; | ||
1858 | int irq; | ||
1859 | |||
1860 | r_ports = platform_get_resource(uap->node, IORESOURCE_MEM, 0); | ||
1861 | irq = platform_get_irq(uap->node, 0); | ||
1862 | if (!r_ports || !irq) | ||
1863 | return -ENODEV; | ||
1864 | |||
1865 | uap->port.mapbase = r_ports->start; | ||
1866 | uap->port.membase = (unsigned char __iomem *) r_ports->start; | ||
1867 | uap->port.iotype = UPIO_MEM; | ||
1868 | uap->port.irq = irq; | ||
1869 | uap->port.uartclk = ZS_CLOCK; | ||
1870 | uap->port.fifosize = 1; | ||
1871 | uap->port.ops = &pmz_pops; | ||
1872 | uap->port.type = PORT_PMAC_ZILOG; | ||
1873 | uap->port.flags = 0; | ||
1874 | |||
1875 | uap->control_reg = uap->port.membase; | ||
1876 | uap->data_reg = uap->control_reg + 4; | ||
1877 | uap->port_type = 0; | ||
1878 | |||
1879 | pmz_convert_to_zs(uap, CS8, 0, 9600); | ||
1880 | |||
1881 | return 0; | ||
1882 | } | ||
1883 | |||
1884 | static int __init pmz_probe(void) | ||
1885 | { | ||
1886 | int err; | ||
1887 | |||
1888 | pmz_ports_count = 0; | ||
1889 | |||
1890 | pmz_ports[0].mate = &pmz_ports[1]; | ||
1891 | pmz_ports[0].port.line = 0; | ||
1892 | pmz_ports[0].flags = PMACZILOG_FLAG_IS_CHANNEL_A; | ||
1893 | pmz_ports[0].node = &scc_a_pdev; | ||
1894 | err = pmz_init_port(&pmz_ports[0]); | ||
1895 | if (err) | ||
1896 | return err; | ||
1897 | pmz_ports_count++; | ||
1898 | |||
1899 | pmz_ports[1].mate = &pmz_ports[0]; | ||
1900 | pmz_ports[1].port.line = 1; | ||
1901 | pmz_ports[1].flags = 0; | ||
1902 | pmz_ports[1].node = &scc_b_pdev; | ||
1903 | err = pmz_init_port(&pmz_ports[1]); | ||
1904 | if (err) | ||
1905 | return err; | ||
1906 | pmz_ports_count++; | ||
1907 | |||
1908 | return 0; | ||
1909 | } | ||
1910 | |||
1911 | static void pmz_dispose_port(struct uart_pmac_port *uap) | ||
1912 | { | ||
1913 | memset(uap, 0, sizeof(struct uart_pmac_port)); | ||
1914 | } | ||
1915 | |||
1916 | static int __init pmz_attach(struct platform_device *pdev) | ||
1917 | { | ||
1918 | int i; | ||
1919 | |||
1920 | for (i = 0; i < pmz_ports_count; i++) | ||
1921 | if (pmz_ports[i].node == pdev) | ||
1922 | return 0; | ||
1923 | return -ENODEV; | ||
1924 | } | ||
1925 | |||
1926 | static int __exit pmz_detach(struct platform_device *pdev) | ||
1927 | { | ||
1928 | return 0; | ||
1929 | } | ||
1930 | |||
1931 | #endif /* !CONFIG_PPC_PMAC */ | ||
1932 | |||
1828 | #ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE | 1933 | #ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE |
1829 | 1934 | ||
1830 | static void pmz_console_write(struct console *con, const char *s, unsigned int count); | 1935 | static void pmz_console_write(struct console *con, const char *s, unsigned int count); |
@@ -1885,28 +1990,44 @@ err_out: | |||
1885 | return rc; | 1990 | return rc; |
1886 | } | 1991 | } |
1887 | 1992 | ||
1993 | #ifdef CONFIG_PPC_PMAC | ||
1994 | |||
1888 | static struct of_device_id pmz_match[] = | 1995 | static struct of_device_id pmz_match[] = |
1889 | { | 1996 | { |
1890 | { | 1997 | { |
1891 | .name = "ch-a", | 1998 | .name = "ch-a", |
1892 | }, | 1999 | }, |
1893 | { | 2000 | { |
1894 | .name = "ch-b", | 2001 | .name = "ch-b", |
1895 | }, | 2002 | }, |
1896 | {}, | 2003 | {}, |
1897 | }; | 2004 | }; |
1898 | MODULE_DEVICE_TABLE (of, pmz_match); | 2005 | MODULE_DEVICE_TABLE (of, pmz_match); |
1899 | 2006 | ||
1900 | static struct macio_driver pmz_driver = | 2007 | static struct macio_driver pmz_driver = { |
1901 | { | 2008 | .driver = { |
1902 | .name = "pmac_zilog", | 2009 | .name = "pmac_zilog", |
1903 | .match_table = pmz_match, | 2010 | .owner = THIS_MODULE, |
2011 | .of_match_table = pmz_match, | ||
2012 | }, | ||
1904 | .probe = pmz_attach, | 2013 | .probe = pmz_attach, |
1905 | .remove = pmz_detach, | 2014 | .remove = pmz_detach, |
1906 | .suspend = pmz_suspend, | 2015 | .suspend = pmz_suspend, |
1907 | .resume = pmz_resume, | 2016 | .resume = pmz_resume, |
2017 | }; | ||
2018 | |||
2019 | #else | ||
2020 | |||
2021 | static struct platform_driver pmz_driver = { | ||
2022 | .remove = __exit_p(pmz_detach), | ||
2023 | .driver = { | ||
2024 | .name = "scc", | ||
2025 | .owner = THIS_MODULE, | ||
2026 | }, | ||
1908 | }; | 2027 | }; |
1909 | 2028 | ||
2029 | #endif /* !CONFIG_PPC_PMAC */ | ||
2030 | |||
1910 | static int __init init_pmz(void) | 2031 | static int __init init_pmz(void) |
1911 | { | 2032 | { |
1912 | int rc, i; | 2033 | int rc, i; |
@@ -1941,19 +2062,27 @@ static int __init init_pmz(void) | |||
1941 | pmz_dispose_port(&pmz_ports[i]); | 2062 | pmz_dispose_port(&pmz_ports[i]); |
1942 | return rc; | 2063 | return rc; |
1943 | } | 2064 | } |
1944 | 2065 | ||
1945 | /* | 2066 | /* |
1946 | * Then we register the macio driver itself | 2067 | * Then we register the macio driver itself |
1947 | */ | 2068 | */ |
2069 | #ifdef CONFIG_PPC_PMAC | ||
1948 | return macio_register_driver(&pmz_driver); | 2070 | return macio_register_driver(&pmz_driver); |
2071 | #else | ||
2072 | return platform_driver_probe(&pmz_driver, pmz_attach); | ||
2073 | #endif | ||
1949 | } | 2074 | } |
1950 | 2075 | ||
1951 | static void __exit exit_pmz(void) | 2076 | static void __exit exit_pmz(void) |
1952 | { | 2077 | { |
1953 | int i; | 2078 | int i; |
1954 | 2079 | ||
2080 | #ifdef CONFIG_PPC_PMAC | ||
1955 | /* Get rid of macio-driver (detach from macio) */ | 2081 | /* Get rid of macio-driver (detach from macio) */ |
1956 | macio_unregister_driver(&pmz_driver); | 2082 | macio_unregister_driver(&pmz_driver); |
2083 | #else | ||
2084 | platform_driver_unregister(&pmz_driver); | ||
2085 | #endif | ||
1957 | 2086 | ||
1958 | for (i = 0; i < pmz_ports_count; i++) { | 2087 | for (i = 0; i < pmz_ports_count; i++) { |
1959 | struct uart_pmac_port *uport = &pmz_ports[i]; | 2088 | struct uart_pmac_port *uport = &pmz_ports[i]; |
@@ -2020,10 +2149,10 @@ static int __init pmz_console_setup(struct console *co, char *options) | |||
2020 | /* | 2149 | /* |
2021 | * XServe's default to 57600 bps | 2150 | * XServe's default to 57600 bps |
2022 | */ | 2151 | */ |
2023 | if (machine_is_compatible("RackMac1,1") | 2152 | if (of_machine_is_compatible("RackMac1,1") |
2024 | || machine_is_compatible("RackMac1,2") | 2153 | || of_machine_is_compatible("RackMac1,2") |
2025 | || machine_is_compatible("MacRISC4")) | 2154 | || of_machine_is_compatible("MacRISC4")) |
2026 | baud = 57600; | 2155 | baud = 57600; |
2027 | 2156 | ||
2028 | /* | 2157 | /* |
2029 | * Check whether an invalid uart number has been specified, and | 2158 | * Check whether an invalid uart number has been specified, and |
diff --git a/drivers/serial/pmac_zilog.h b/drivers/serial/pmac_zilog.h index 570b0d925e83..cbc34fbb1b20 100644 --- a/drivers/serial/pmac_zilog.h +++ b/drivers/serial/pmac_zilog.h | |||
@@ -1,7 +1,15 @@ | |||
1 | #ifndef __PMAC_ZILOG_H__ | 1 | #ifndef __PMAC_ZILOG_H__ |
2 | #define __PMAC_ZILOG_H__ | 2 | #define __PMAC_ZILOG_H__ |
3 | 3 | ||
4 | #define pmz_debug(fmt,arg...) dev_dbg(&uap->dev->ofdev.dev, fmt, ## arg) | 4 | #ifdef CONFIG_PPC_PMAC |
5 | #define pmz_debug(fmt, arg...) dev_dbg(&uap->dev->ofdev.dev, fmt, ## arg) | ||
6 | #define pmz_error(fmt, arg...) dev_err(&uap->dev->ofdev.dev, fmt, ## arg) | ||
7 | #define pmz_info(fmt, arg...) dev_info(&uap->dev->ofdev.dev, fmt, ## arg) | ||
8 | #else | ||
9 | #define pmz_debug(fmt, arg...) dev_dbg(&uap->node->dev, fmt, ## arg) | ||
10 | #define pmz_error(fmt, arg...) dev_err(&uap->node->dev, fmt, ## arg) | ||
11 | #define pmz_info(fmt, arg...) dev_info(&uap->node->dev, fmt, ## arg) | ||
12 | #endif | ||
5 | 13 | ||
6 | /* | 14 | /* |
7 | * At most 2 ESCCs with 2 ports each | 15 | * At most 2 ESCCs with 2 ports each |
@@ -17,6 +25,7 @@ struct uart_pmac_port { | |||
17 | struct uart_port port; | 25 | struct uart_port port; |
18 | struct uart_pmac_port *mate; | 26 | struct uart_pmac_port *mate; |
19 | 27 | ||
28 | #ifdef CONFIG_PPC_PMAC | ||
20 | /* macio_dev for the escc holding this port (maybe be null on | 29 | /* macio_dev for the escc holding this port (maybe be null on |
21 | * early inited port) | 30 | * early inited port) |
22 | */ | 31 | */ |
@@ -25,6 +34,9 @@ struct uart_pmac_port { | |||
25 | * of "escc" node (ie. ch-a or ch-b) | 34 | * of "escc" node (ie. ch-a or ch-b) |
26 | */ | 35 | */ |
27 | struct device_node *node; | 36 | struct device_node *node; |
37 | #else | ||
38 | struct platform_device *node; | ||
39 | #endif | ||
28 | 40 | ||
29 | /* Port type as obtained from device tree (IRDA, modem, ...) */ | 41 | /* Port type as obtained from device tree (IRDA, modem, ...) */ |
30 | int port_type; | 42 | int port_type; |
@@ -55,10 +67,12 @@ struct uart_pmac_port { | |||
55 | volatile u8 __iomem *control_reg; | 67 | volatile u8 __iomem *control_reg; |
56 | volatile u8 __iomem *data_reg; | 68 | volatile u8 __iomem *data_reg; |
57 | 69 | ||
70 | #ifdef CONFIG_PPC_PMAC | ||
58 | unsigned int tx_dma_irq; | 71 | unsigned int tx_dma_irq; |
59 | unsigned int rx_dma_irq; | 72 | unsigned int rx_dma_irq; |
60 | volatile struct dbdma_regs __iomem *tx_dma_regs; | 73 | volatile struct dbdma_regs __iomem *tx_dma_regs; |
61 | volatile struct dbdma_regs __iomem *rx_dma_regs; | 74 | volatile struct dbdma_regs __iomem *rx_dma_regs; |
75 | #endif | ||
62 | 76 | ||
63 | struct ktermios termios_cache; | 77 | struct ktermios termios_cache; |
64 | }; | 78 | }; |
@@ -73,7 +87,7 @@ static inline struct uart_pmac_port *pmz_get_port_A(struct uart_pmac_port *uap) | |||
73 | } | 87 | } |
74 | 88 | ||
75 | /* | 89 | /* |
76 | * Register acessors. Note that we don't need to enforce a recovery | 90 | * Register accessors. Note that we don't need to enforce a recovery |
77 | * delay on PCI PowerMac hardware, it's dealt in HW by the MacIO chip, | 91 | * delay on PCI PowerMac hardware, it's dealt in HW by the MacIO chip, |
78 | * though if we try to use this driver on older machines, we might have | 92 | * though if we try to use this driver on older machines, we might have |
79 | * to add it back | 93 | * to add it back |
@@ -113,7 +127,7 @@ static inline void zssync(struct uart_pmac_port *port) | |||
113 | #define BRG_TO_BPS(brg, freq) ((freq) / 2 / ((brg) + 2)) | 127 | #define BRG_TO_BPS(brg, freq) ((freq) / 2 / ((brg) + 2)) |
114 | #define BPS_TO_BRG(bps, freq) ((((freq) + (bps)) / (2 * (bps))) - 2) | 128 | #define BPS_TO_BRG(bps, freq) ((((freq) + (bps)) / (2 * (bps))) - 2) |
115 | 129 | ||
116 | #define ZS_CLOCK 3686400 /* Z8530 RTxC input clock rate */ | 130 | #define ZS_CLOCK 3686400 /* Z8530 RTxC input clock rate */ |
117 | 131 | ||
118 | /* The Zilog register set */ | 132 | /* The Zilog register set */ |
119 | 133 | ||
@@ -171,7 +185,7 @@ static inline void zssync(struct uart_pmac_port *port) | |||
171 | 185 | ||
172 | /* Write Register 3 */ | 186 | /* Write Register 3 */ |
173 | 187 | ||
174 | #define RxENABLE 0x1 /* Rx Enable */ | 188 | #define RxENABLE 0x1 /* Rx Enable */ |
175 | #define SYNC_L_INH 0x2 /* Sync Character Load Inhibit */ | 189 | #define SYNC_L_INH 0x2 /* Sync Character Load Inhibit */ |
176 | #define ADD_SM 0x4 /* Address Search Mode (SDLC) */ | 190 | #define ADD_SM 0x4 /* Address Search Mode (SDLC) */ |
177 | #define RxCRC_ENAB 0x8 /* Rx CRC Enable */ | 191 | #define RxCRC_ENAB 0x8 /* Rx CRC Enable */ |
@@ -185,7 +199,7 @@ static inline void zssync(struct uart_pmac_port *port) | |||
185 | 199 | ||
186 | /* Write Register 4 */ | 200 | /* Write Register 4 */ |
187 | 201 | ||
188 | #define PAR_ENAB 0x1 /* Parity Enable */ | 202 | #define PAR_ENAB 0x1 /* Parity Enable */ |
189 | #define PAR_EVEN 0x2 /* Parity Even/Odd* */ | 203 | #define PAR_EVEN 0x2 /* Parity Even/Odd* */ |
190 | 204 | ||
191 | #define SYNC_ENAB 0 /* Sync Modes Enable */ | 205 | #define SYNC_ENAB 0 /* Sync Modes Enable */ |
@@ -210,7 +224,7 @@ static inline void zssync(struct uart_pmac_port *port) | |||
210 | #define TxCRC_ENAB 0x1 /* Tx CRC Enable */ | 224 | #define TxCRC_ENAB 0x1 /* Tx CRC Enable */ |
211 | #define RTS 0x2 /* RTS */ | 225 | #define RTS 0x2 /* RTS */ |
212 | #define SDLC_CRC 0x4 /* SDLC/CRC-16 */ | 226 | #define SDLC_CRC 0x4 /* SDLC/CRC-16 */ |
213 | #define TxENABLE 0x8 /* Tx Enable */ | 227 | #define TxENABLE 0x8 /* Tx Enable */ |
214 | #define SND_BRK 0x10 /* Send Break */ | 228 | #define SND_BRK 0x10 /* Send Break */ |
215 | #define Tx5 0x0 /* Tx 5 bits (or less)/character */ | 229 | #define Tx5 0x0 /* Tx 5 bits (or less)/character */ |
216 | #define Tx7 0x20 /* Tx 7 bits/character */ | 230 | #define Tx7 0x20 /* Tx 7 bits/character */ |
@@ -372,11 +386,11 @@ static inline void zssync(struct uart_pmac_port *port) | |||
372 | #define ZS_TX_ACTIVE(UP) ((UP)->flags & PMACZILOG_FLAG_TX_ACTIVE) | 386 | #define ZS_TX_ACTIVE(UP) ((UP)->flags & PMACZILOG_FLAG_TX_ACTIVE) |
373 | #define ZS_WANTS_MODEM_STATUS(UP) ((UP)->flags & PMACZILOG_FLAG_MODEM_STATUS) | 387 | #define ZS_WANTS_MODEM_STATUS(UP) ((UP)->flags & PMACZILOG_FLAG_MODEM_STATUS) |
374 | #define ZS_IS_IRDA(UP) ((UP)->flags & PMACZILOG_FLAG_IS_IRDA) | 388 | #define ZS_IS_IRDA(UP) ((UP)->flags & PMACZILOG_FLAG_IS_IRDA) |
375 | #define ZS_IS_INTMODEM(UP) ((UP)->flags & PMACZILOG_FLAG_IS_INTMODEM) | 389 | #define ZS_IS_INTMODEM(UP) ((UP)->flags & PMACZILOG_FLAG_IS_INTMODEM) |
376 | #define ZS_HAS_DMA(UP) ((UP)->flags & PMACZILOG_FLAG_HAS_DMA) | 390 | #define ZS_HAS_DMA(UP) ((UP)->flags & PMACZILOG_FLAG_HAS_DMA) |
377 | #define ZS_IS_ASLEEP(UP) ((UP)->flags & PMACZILOG_FLAG_IS_ASLEEP) | 391 | #define ZS_IS_ASLEEP(UP) ((UP)->flags & PMACZILOG_FLAG_IS_ASLEEP) |
378 | #define ZS_IS_OPEN(UP) ((UP)->flags & PMACZILOG_FLAG_IS_OPEN) | 392 | #define ZS_IS_OPEN(UP) ((UP)->flags & PMACZILOG_FLAG_IS_OPEN) |
379 | #define ZS_IS_IRQ_ON(UP) ((UP)->flags & PMACZILOG_FLAG_IS_IRQ_ON) | 393 | #define ZS_IS_IRQ_ON(UP) ((UP)->flags & PMACZILOG_FLAG_IS_IRQ_ON) |
380 | #define ZS_IS_EXTCLK(UP) ((UP)->flags & PMACZILOG_FLAG_IS_EXTCLK) | 394 | #define ZS_IS_EXTCLK(UP) ((UP)->flags & PMACZILOG_FLAG_IS_EXTCLK) |
381 | 395 | ||
382 | #endif /* __PMAC_ZILOG_H__ */ | 396 | #endif /* __PMAC_ZILOG_H__ */ |
diff --git a/drivers/serial/pnx8xxx_uart.c b/drivers/serial/pnx8xxx_uart.c index 1bb8f1b45767..0aa75a97531c 100644 --- a/drivers/serial/pnx8xxx_uart.c +++ b/drivers/serial/pnx8xxx_uart.c | |||
@@ -100,7 +100,7 @@ static void pnx8xxx_mctrl_check(struct pnx8xxx_port *sport) | |||
100 | if (changed & TIOCM_CTS) | 100 | if (changed & TIOCM_CTS) |
101 | uart_handle_cts_change(&sport->port, status & TIOCM_CTS); | 101 | uart_handle_cts_change(&sport->port, status & TIOCM_CTS); |
102 | 102 | ||
103 | wake_up_interruptible(&sport->port.info->delta_msr_wait); | 103 | wake_up_interruptible(&sport->port.state->port.delta_msr_wait); |
104 | } | 104 | } |
105 | 105 | ||
106 | /* | 106 | /* |
@@ -112,7 +112,7 @@ static void pnx8xxx_timeout(unsigned long data) | |||
112 | struct pnx8xxx_port *sport = (struct pnx8xxx_port *)data; | 112 | struct pnx8xxx_port *sport = (struct pnx8xxx_port *)data; |
113 | unsigned long flags; | 113 | unsigned long flags; |
114 | 114 | ||
115 | if (sport->port.info) { | 115 | if (sport->port.state) { |
116 | spin_lock_irqsave(&sport->port.lock, flags); | 116 | spin_lock_irqsave(&sport->port.lock, flags); |
117 | pnx8xxx_mctrl_check(sport); | 117 | pnx8xxx_mctrl_check(sport); |
118 | spin_unlock_irqrestore(&sport->port.lock, flags); | 118 | spin_unlock_irqrestore(&sport->port.lock, flags); |
@@ -181,7 +181,7 @@ static void pnx8xxx_enable_ms(struct uart_port *port) | |||
181 | 181 | ||
182 | static void pnx8xxx_rx_chars(struct pnx8xxx_port *sport) | 182 | static void pnx8xxx_rx_chars(struct pnx8xxx_port *sport) |
183 | { | 183 | { |
184 | struct tty_struct *tty = sport->port.info->port.tty; | 184 | struct tty_struct *tty = sport->port.state->port.tty; |
185 | unsigned int status, ch, flg; | 185 | unsigned int status, ch, flg; |
186 | 186 | ||
187 | status = FIFO_TO_SM(serial_in(sport, PNX8XXX_FIFO)) | | 187 | status = FIFO_TO_SM(serial_in(sport, PNX8XXX_FIFO)) | |
@@ -243,7 +243,7 @@ static void pnx8xxx_rx_chars(struct pnx8xxx_port *sport) | |||
243 | 243 | ||
244 | static void pnx8xxx_tx_chars(struct pnx8xxx_port *sport) | 244 | static void pnx8xxx_tx_chars(struct pnx8xxx_port *sport) |
245 | { | 245 | { |
246 | struct circ_buf *xmit = &sport->port.info->xmit; | 246 | struct circ_buf *xmit = &sport->port.state->xmit; |
247 | 247 | ||
248 | if (sport->port.x_char) { | 248 | if (sport->port.x_char) { |
249 | serial_out(sport, PNX8XXX_FIFO, sport->port.x_char); | 249 | serial_out(sport, PNX8XXX_FIFO, sport->port.x_char); |
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c index a48a8a13d87b..1102a39b44f5 100644 --- a/drivers/serial/pxa.c +++ b/drivers/serial/pxa.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <linux/serial_core.h> | 44 | #include <linux/serial_core.h> |
45 | #include <linux/clk.h> | 45 | #include <linux/clk.h> |
46 | #include <linux/io.h> | 46 | #include <linux/io.h> |
47 | #include <linux/slab.h> | ||
47 | 48 | ||
48 | struct uart_pxa_port { | 49 | struct uart_pxa_port { |
49 | struct uart_port port; | 50 | struct uart_port port; |
@@ -96,7 +97,7 @@ static void serial_pxa_stop_rx(struct uart_port *port) | |||
96 | 97 | ||
97 | static inline void receive_chars(struct uart_pxa_port *up, int *status) | 98 | static inline void receive_chars(struct uart_pxa_port *up, int *status) |
98 | { | 99 | { |
99 | struct tty_struct *tty = up->port.info->port.tty; | 100 | struct tty_struct *tty = up->port.state->port.tty; |
100 | unsigned int ch, flag; | 101 | unsigned int ch, flag; |
101 | int max_count = 256; | 102 | int max_count = 256; |
102 | 103 | ||
@@ -161,7 +162,7 @@ static inline void receive_chars(struct uart_pxa_port *up, int *status) | |||
161 | 162 | ||
162 | static void transmit_chars(struct uart_pxa_port *up) | 163 | static void transmit_chars(struct uart_pxa_port *up) |
163 | { | 164 | { |
164 | struct circ_buf *xmit = &up->port.info->xmit; | 165 | struct circ_buf *xmit = &up->port.state->xmit; |
165 | int count; | 166 | int count; |
166 | 167 | ||
167 | if (up->port.x_char) { | 168 | if (up->port.x_char) { |
@@ -220,7 +221,7 @@ static inline void check_modem_status(struct uart_pxa_port *up) | |||
220 | if (status & UART_MSR_DCTS) | 221 | if (status & UART_MSR_DCTS) |
221 | uart_handle_cts_change(&up->port, status & UART_MSR_CTS); | 222 | uart_handle_cts_change(&up->port, status & UART_MSR_CTS); |
222 | 223 | ||
223 | wake_up_interruptible(&up->port.info->delta_msr_wait); | 224 | wake_up_interruptible(&up->port.state->port.delta_msr_wait); |
224 | } | 225 | } |
225 | 226 | ||
226 | /* | 227 | /* |
@@ -438,6 +439,7 @@ serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios, | |||
438 | unsigned char cval, fcr = 0; | 439 | unsigned char cval, fcr = 0; |
439 | unsigned long flags; | 440 | unsigned long flags; |
440 | unsigned int baud, quot; | 441 | unsigned int baud, quot; |
442 | unsigned int dll; | ||
441 | 443 | ||
442 | switch (termios->c_cflag & CSIZE) { | 444 | switch (termios->c_cflag & CSIZE) { |
443 | case CS5: | 445 | case CS5: |
@@ -534,10 +536,18 @@ serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios, | |||
534 | else | 536 | else |
535 | up->mcr &= ~UART_MCR_AFE; | 537 | up->mcr &= ~UART_MCR_AFE; |
536 | 538 | ||
537 | serial_out(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */ | 539 | serial_out(up, UART_LCR, cval | UART_LCR_DLAB); /* set DLAB */ |
538 | serial_out(up, UART_DLL, quot & 0xff); /* LS of divisor */ | 540 | serial_out(up, UART_DLL, quot & 0xff); /* LS of divisor */ |
541 | |||
542 | /* | ||
543 | * work around Errata #75 according to Intel(R) PXA27x Processor Family | ||
544 | * Specification Update (Nov 2005) | ||
545 | */ | ||
546 | dll = serial_in(up, UART_DLL); | ||
547 | WARN_ON(dll != (quot & 0xff)); | ||
548 | |||
539 | serial_out(up, UART_DLM, quot >> 8); /* MS of divisor */ | 549 | serial_out(up, UART_DLM, quot >> 8); /* MS of divisor */ |
540 | serial_out(up, UART_LCR, cval); /* reset DLAB */ | 550 | serial_out(up, UART_LCR, cval); /* reset DLAB */ |
541 | up->lcr = cval; /* Save LCR */ | 551 | up->lcr = cval; /* Save LCR */ |
542 | serial_pxa_set_mctrl(&up->port, up->port.mctrl); | 552 | serial_pxa_set_mctrl(&up->port, up->port.mctrl); |
543 | serial_out(up, UART_FCR, fcr); | 553 | serial_out(up, UART_FCR, fcr); |
@@ -726,9 +736,10 @@ static struct uart_driver serial_pxa_reg = { | |||
726 | .cons = PXA_CONSOLE, | 736 | .cons = PXA_CONSOLE, |
727 | }; | 737 | }; |
728 | 738 | ||
729 | static int serial_pxa_suspend(struct platform_device *dev, pm_message_t state) | 739 | #ifdef CONFIG_PM |
740 | static int serial_pxa_suspend(struct device *dev) | ||
730 | { | 741 | { |
731 | struct uart_pxa_port *sport = platform_get_drvdata(dev); | 742 | struct uart_pxa_port *sport = dev_get_drvdata(dev); |
732 | 743 | ||
733 | if (sport) | 744 | if (sport) |
734 | uart_suspend_port(&serial_pxa_reg, &sport->port); | 745 | uart_suspend_port(&serial_pxa_reg, &sport->port); |
@@ -736,9 +747,9 @@ static int serial_pxa_suspend(struct platform_device *dev, pm_message_t state) | |||
736 | return 0; | 747 | return 0; |
737 | } | 748 | } |
738 | 749 | ||
739 | static int serial_pxa_resume(struct platform_device *dev) | 750 | static int serial_pxa_resume(struct device *dev) |
740 | { | 751 | { |
741 | struct uart_pxa_port *sport = platform_get_drvdata(dev); | 752 | struct uart_pxa_port *sport = dev_get_drvdata(dev); |
742 | 753 | ||
743 | if (sport) | 754 | if (sport) |
744 | uart_resume_port(&serial_pxa_reg, &sport->port); | 755 | uart_resume_port(&serial_pxa_reg, &sport->port); |
@@ -746,6 +757,12 @@ static int serial_pxa_resume(struct platform_device *dev) | |||
746 | return 0; | 757 | return 0; |
747 | } | 758 | } |
748 | 759 | ||
760 | static const struct dev_pm_ops serial_pxa_pm_ops = { | ||
761 | .suspend = serial_pxa_suspend, | ||
762 | .resume = serial_pxa_resume, | ||
763 | }; | ||
764 | #endif | ||
765 | |||
749 | static int serial_pxa_probe(struct platform_device *dev) | 766 | static int serial_pxa_probe(struct platform_device *dev) |
750 | { | 767 | { |
751 | struct uart_pxa_port *sport; | 768 | struct uart_pxa_port *sport; |
@@ -825,11 +842,12 @@ static struct platform_driver serial_pxa_driver = { | |||
825 | .probe = serial_pxa_probe, | 842 | .probe = serial_pxa_probe, |
826 | .remove = serial_pxa_remove, | 843 | .remove = serial_pxa_remove, |
827 | 844 | ||
828 | .suspend = serial_pxa_suspend, | ||
829 | .resume = serial_pxa_resume, | ||
830 | .driver = { | 845 | .driver = { |
831 | .name = "pxa2xx-uart", | 846 | .name = "pxa2xx-uart", |
832 | .owner = THIS_MODULE, | 847 | .owner = THIS_MODULE, |
848 | #ifdef CONFIG_PM | ||
849 | .pm = &serial_pxa_pm_ops, | ||
850 | #endif | ||
833 | }, | 851 | }, |
834 | }; | 852 | }; |
835 | 853 | ||
diff --git a/drivers/serial/s3c2400.c b/drivers/serial/s3c2400.c index fb00ed5296e6..fed1a9a1ffb4 100644 --- a/drivers/serial/s3c2400.c +++ b/drivers/serial/s3c2400.c | |||
@@ -76,7 +76,7 @@ static int s3c2400_serial_probe(struct platform_device *dev) | |||
76 | return s3c24xx_serial_probe(dev, &s3c2400_uart_inf); | 76 | return s3c24xx_serial_probe(dev, &s3c2400_uart_inf); |
77 | } | 77 | } |
78 | 78 | ||
79 | static struct platform_driver s3c2400_serial_drv = { | 79 | static struct platform_driver s3c2400_serial_driver = { |
80 | .probe = s3c2400_serial_probe, | 80 | .probe = s3c2400_serial_probe, |
81 | .remove = __devexit_p(s3c24xx_serial_remove), | 81 | .remove = __devexit_p(s3c24xx_serial_remove), |
82 | .driver = { | 82 | .driver = { |
@@ -85,16 +85,16 @@ static struct platform_driver s3c2400_serial_drv = { | |||
85 | }, | 85 | }, |
86 | }; | 86 | }; |
87 | 87 | ||
88 | s3c24xx_console_init(&s3c2400_serial_drv, &s3c2400_uart_inf); | 88 | s3c24xx_console_init(&s3c2400_serial_driver, &s3c2400_uart_inf); |
89 | 89 | ||
90 | static inline int s3c2400_serial_init(void) | 90 | static inline int s3c2400_serial_init(void) |
91 | { | 91 | { |
92 | return s3c24xx_serial_init(&s3c2400_serial_drv, &s3c2400_uart_inf); | 92 | return s3c24xx_serial_init(&s3c2400_serial_driver, &s3c2400_uart_inf); |
93 | } | 93 | } |
94 | 94 | ||
95 | static inline void s3c2400_serial_exit(void) | 95 | static inline void s3c2400_serial_exit(void) |
96 | { | 96 | { |
97 | platform_driver_unregister(&s3c2400_serial_drv); | 97 | platform_driver_unregister(&s3c2400_serial_driver); |
98 | } | 98 | } |
99 | 99 | ||
100 | module_init(s3c2400_serial_init); | 100 | module_init(s3c2400_serial_init); |
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c index b5d7cbcba2ae..73f089d3efd6 100644 --- a/drivers/serial/s3c2410.c +++ b/drivers/serial/s3c2410.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * | 2 | * |
3 | * Driver for Samsung S3C2410 SoC onboard UARTs. | 3 | * Driver for Samsung S3C2410 SoC onboard UARTs. |
4 | * | 4 | * |
5 | * Ben Dooks, Copyright (c) 2003-2005,2008 Simtec Electronics | 5 | * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics |
6 | * http://armlinux.simtec.co.uk/ | 6 | * http://armlinux.simtec.co.uk/ |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
@@ -88,7 +88,7 @@ static int s3c2410_serial_probe(struct platform_device *dev) | |||
88 | return s3c24xx_serial_probe(dev, &s3c2410_uart_inf); | 88 | return s3c24xx_serial_probe(dev, &s3c2410_uart_inf); |
89 | } | 89 | } |
90 | 90 | ||
91 | static struct platform_driver s3c2410_serial_drv = { | 91 | static struct platform_driver s3c2410_serial_driver = { |
92 | .probe = s3c2410_serial_probe, | 92 | .probe = s3c2410_serial_probe, |
93 | .remove = __devexit_p(s3c24xx_serial_remove), | 93 | .remove = __devexit_p(s3c24xx_serial_remove), |
94 | .driver = { | 94 | .driver = { |
@@ -97,16 +97,16 @@ static struct platform_driver s3c2410_serial_drv = { | |||
97 | }, | 97 | }, |
98 | }; | 98 | }; |
99 | 99 | ||
100 | s3c24xx_console_init(&s3c2410_serial_drv, &s3c2410_uart_inf); | 100 | s3c24xx_console_init(&s3c2410_serial_driver, &s3c2410_uart_inf); |
101 | 101 | ||
102 | static int __init s3c2410_serial_init(void) | 102 | static int __init s3c2410_serial_init(void) |
103 | { | 103 | { |
104 | return s3c24xx_serial_init(&s3c2410_serial_drv, &s3c2410_uart_inf); | 104 | return s3c24xx_serial_init(&s3c2410_serial_driver, &s3c2410_uart_inf); |
105 | } | 105 | } |
106 | 106 | ||
107 | static void __exit s3c2410_serial_exit(void) | 107 | static void __exit s3c2410_serial_exit(void) |
108 | { | 108 | { |
109 | platform_driver_unregister(&s3c2410_serial_drv); | 109 | platform_driver_unregister(&s3c2410_serial_driver); |
110 | } | 110 | } |
111 | 111 | ||
112 | module_init(s3c2410_serial_init); | 112 | module_init(s3c2410_serial_init); |
diff --git a/drivers/serial/s3c2412.c b/drivers/serial/s3c2412.c index 11dcb90bdfef..1700b1a2fb7e 100644 --- a/drivers/serial/s3c2412.c +++ b/drivers/serial/s3c2412.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * | 2 | * |
3 | * Driver for Samsung S3C2412 and S3C2413 SoC onboard UARTs. | 3 | * Driver for Samsung S3C2412 and S3C2413 SoC onboard UARTs. |
4 | * | 4 | * |
5 | * Ben Dooks, Copyright (c) 2003-2005,2008 Simtec Electronics | 5 | * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics |
6 | * http://armlinux.simtec.co.uk/ | 6 | * http://armlinux.simtec.co.uk/ |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
@@ -102,6 +102,7 @@ static struct s3c24xx_uart_info s3c2412_uart_inf = { | |||
102 | .name = "Samsung S3C2412 UART", | 102 | .name = "Samsung S3C2412 UART", |
103 | .type = PORT_S3C2412, | 103 | .type = PORT_S3C2412, |
104 | .fifosize = 64, | 104 | .fifosize = 64, |
105 | .has_divslot = 1, | ||
105 | .rx_fifomask = S3C2440_UFSTAT_RXMASK, | 106 | .rx_fifomask = S3C2440_UFSTAT_RXMASK, |
106 | .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT, | 107 | .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT, |
107 | .rx_fifofull = S3C2440_UFSTAT_RXFULL, | 108 | .rx_fifofull = S3C2440_UFSTAT_RXFULL, |
@@ -121,7 +122,7 @@ static int s3c2412_serial_probe(struct platform_device *dev) | |||
121 | return s3c24xx_serial_probe(dev, &s3c2412_uart_inf); | 122 | return s3c24xx_serial_probe(dev, &s3c2412_uart_inf); |
122 | } | 123 | } |
123 | 124 | ||
124 | static struct platform_driver s3c2412_serial_drv = { | 125 | static struct platform_driver s3c2412_serial_driver = { |
125 | .probe = s3c2412_serial_probe, | 126 | .probe = s3c2412_serial_probe, |
126 | .remove = __devexit_p(s3c24xx_serial_remove), | 127 | .remove = __devexit_p(s3c24xx_serial_remove), |
127 | .driver = { | 128 | .driver = { |
@@ -130,16 +131,16 @@ static struct platform_driver s3c2412_serial_drv = { | |||
130 | }, | 131 | }, |
131 | }; | 132 | }; |
132 | 133 | ||
133 | s3c24xx_console_init(&s3c2412_serial_drv, &s3c2412_uart_inf); | 134 | s3c24xx_console_init(&s3c2412_serial_driver, &s3c2412_uart_inf); |
134 | 135 | ||
135 | static inline int s3c2412_serial_init(void) | 136 | static inline int s3c2412_serial_init(void) |
136 | { | 137 | { |
137 | return s3c24xx_serial_init(&s3c2412_serial_drv, &s3c2412_uart_inf); | 138 | return s3c24xx_serial_init(&s3c2412_serial_driver, &s3c2412_uart_inf); |
138 | } | 139 | } |
139 | 140 | ||
140 | static inline void s3c2412_serial_exit(void) | 141 | static inline void s3c2412_serial_exit(void) |
141 | { | 142 | { |
142 | platform_driver_unregister(&s3c2412_serial_drv); | 143 | platform_driver_unregister(&s3c2412_serial_driver); |
143 | } | 144 | } |
144 | 145 | ||
145 | module_init(s3c2412_serial_init); | 146 | module_init(s3c2412_serial_init); |
diff --git a/drivers/serial/s3c2440.c b/drivers/serial/s3c2440.c index 06c5b0cc47a3..094cc3904b13 100644 --- a/drivers/serial/s3c2440.c +++ b/drivers/serial/s3c2440.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * | 2 | * |
3 | * Driver for Samsung S3C2440 and S3C2442 SoC onboard UARTs. | 3 | * Driver for Samsung S3C2440 and S3C2442 SoC onboard UARTs. |
4 | * | 4 | * |
5 | * Ben Dooks, Copyright (c) 2003-2005,2008 Simtec Electronics | 5 | * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics |
6 | * http://armlinux.simtec.co.uk/ | 6 | * http://armlinux.simtec.co.uk/ |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
@@ -151,7 +151,7 @@ static int s3c2440_serial_probe(struct platform_device *dev) | |||
151 | return s3c24xx_serial_probe(dev, &s3c2440_uart_inf); | 151 | return s3c24xx_serial_probe(dev, &s3c2440_uart_inf); |
152 | } | 152 | } |
153 | 153 | ||
154 | static struct platform_driver s3c2440_serial_drv = { | 154 | static struct platform_driver s3c2440_serial_driver = { |
155 | .probe = s3c2440_serial_probe, | 155 | .probe = s3c2440_serial_probe, |
156 | .remove = __devexit_p(s3c24xx_serial_remove), | 156 | .remove = __devexit_p(s3c24xx_serial_remove), |
157 | .driver = { | 157 | .driver = { |
@@ -160,16 +160,16 @@ static struct platform_driver s3c2440_serial_drv = { | |||
160 | }, | 160 | }, |
161 | }; | 161 | }; |
162 | 162 | ||
163 | s3c24xx_console_init(&s3c2440_serial_drv, &s3c2440_uart_inf); | 163 | s3c24xx_console_init(&s3c2440_serial_driver, &s3c2440_uart_inf); |
164 | 164 | ||
165 | static int __init s3c2440_serial_init(void) | 165 | static int __init s3c2440_serial_init(void) |
166 | { | 166 | { |
167 | return s3c24xx_serial_init(&s3c2440_serial_drv, &s3c2440_uart_inf); | 167 | return s3c24xx_serial_init(&s3c2440_serial_driver, &s3c2440_uart_inf); |
168 | } | 168 | } |
169 | 169 | ||
170 | static void __exit s3c2440_serial_exit(void) | 170 | static void __exit s3c2440_serial_exit(void) |
171 | { | 171 | { |
172 | platform_driver_unregister(&s3c2440_serial_drv); | 172 | platform_driver_unregister(&s3c2440_serial_driver); |
173 | } | 173 | } |
174 | 174 | ||
175 | module_init(s3c2440_serial_init); | 175 | module_init(s3c2440_serial_init); |
diff --git a/drivers/serial/s3c24a0.c b/drivers/serial/s3c24a0.c index 786a067d62ac..fad6083ca427 100644 --- a/drivers/serial/s3c24a0.c +++ b/drivers/serial/s3c24a0.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * | 6 | * |
7 | * Author: Sandeep Patil <sandeep.patil@azingo.com> | 7 | * Author: Sandeep Patil <sandeep.patil@azingo.com> |
8 | * | 8 | * |
9 | * Ben Dooks, Copyright (c) 2003-2005,2008 Simtec Electronics | 9 | * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics |
10 | * http://armlinux.simtec.co.uk/ | 10 | * http://armlinux.simtec.co.uk/ |
11 | * | 11 | * |
12 | * This program is free software; you can redistribute it and/or modify | 12 | * This program is free software; you can redistribute it and/or modify |
@@ -92,7 +92,7 @@ static int s3c24a0_serial_probe(struct platform_device *dev) | |||
92 | return s3c24xx_serial_probe(dev, &s3c24a0_uart_inf); | 92 | return s3c24xx_serial_probe(dev, &s3c24a0_uart_inf); |
93 | } | 93 | } |
94 | 94 | ||
95 | static struct platform_driver s3c24a0_serial_drv = { | 95 | static struct platform_driver s3c24a0_serial_driver = { |
96 | .probe = s3c24a0_serial_probe, | 96 | .probe = s3c24a0_serial_probe, |
97 | .remove = __devexit_p(s3c24xx_serial_remove), | 97 | .remove = __devexit_p(s3c24xx_serial_remove), |
98 | .driver = { | 98 | .driver = { |
@@ -101,16 +101,16 @@ static struct platform_driver s3c24a0_serial_drv = { | |||
101 | }, | 101 | }, |
102 | }; | 102 | }; |
103 | 103 | ||
104 | s3c24xx_console_init(&s3c24a0_serial_drv, &s3c24a0_uart_inf); | 104 | s3c24xx_console_init(&s3c24a0_serial_driver, &s3c24a0_uart_inf); |
105 | 105 | ||
106 | static int __init s3c24a0_serial_init(void) | 106 | static int __init s3c24a0_serial_init(void) |
107 | { | 107 | { |
108 | return s3c24xx_serial_init(&s3c24a0_serial_drv, &s3c24a0_uart_inf); | 108 | return s3c24xx_serial_init(&s3c24a0_serial_driver, &s3c24a0_uart_inf); |
109 | } | 109 | } |
110 | 110 | ||
111 | static void __exit s3c24a0_serial_exit(void) | 111 | static void __exit s3c24a0_serial_exit(void) |
112 | { | 112 | { |
113 | platform_driver_unregister(&s3c24a0_serial_drv); | 113 | platform_driver_unregister(&s3c24a0_serial_driver); |
114 | } | 114 | } |
115 | 115 | ||
116 | module_init(s3c24a0_serial_init); | 116 | module_init(s3c24a0_serial_init); |
diff --git a/drivers/serial/s3c6400.c b/drivers/serial/s3c6400.c index 48f1a3781f0d..4be92ab50058 100644 --- a/drivers/serial/s3c6400.c +++ b/drivers/serial/s3c6400.c | |||
@@ -122,7 +122,7 @@ static int s3c6400_serial_probe(struct platform_device *dev) | |||
122 | return s3c24xx_serial_probe(dev, &s3c6400_uart_inf); | 122 | return s3c24xx_serial_probe(dev, &s3c6400_uart_inf); |
123 | } | 123 | } |
124 | 124 | ||
125 | static struct platform_driver s3c6400_serial_drv = { | 125 | static struct platform_driver s3c6400_serial_driver = { |
126 | .probe = s3c6400_serial_probe, | 126 | .probe = s3c6400_serial_probe, |
127 | .remove = __devexit_p(s3c24xx_serial_remove), | 127 | .remove = __devexit_p(s3c24xx_serial_remove), |
128 | .driver = { | 128 | .driver = { |
@@ -131,16 +131,16 @@ static struct platform_driver s3c6400_serial_drv = { | |||
131 | }, | 131 | }, |
132 | }; | 132 | }; |
133 | 133 | ||
134 | s3c24xx_console_init(&s3c6400_serial_drv, &s3c6400_uart_inf); | 134 | s3c24xx_console_init(&s3c6400_serial_driver, &s3c6400_uart_inf); |
135 | 135 | ||
136 | static int __init s3c6400_serial_init(void) | 136 | static int __init s3c6400_serial_init(void) |
137 | { | 137 | { |
138 | return s3c24xx_serial_init(&s3c6400_serial_drv, &s3c6400_uart_inf); | 138 | return s3c24xx_serial_init(&s3c6400_serial_driver, &s3c6400_uart_inf); |
139 | } | 139 | } |
140 | 140 | ||
141 | static void __exit s3c6400_serial_exit(void) | 141 | static void __exit s3c6400_serial_exit(void) |
142 | { | 142 | { |
143 | platform_driver_unregister(&s3c6400_serial_drv); | 143 | platform_driver_unregister(&s3c6400_serial_driver); |
144 | } | 144 | } |
145 | 145 | ||
146 | module_init(s3c6400_serial_init); | 146 | module_init(s3c6400_serial_init); |
diff --git a/drivers/serial/s5pv210.c b/drivers/serial/s5pv210.c new file mode 100644 index 000000000000..6ebccd70a707 --- /dev/null +++ b/drivers/serial/s5pv210.c | |||
@@ -0,0 +1,162 @@ | |||
1 | /* linux/drivers/serial/s5pv210.c | ||
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com/ | ||
5 | * | ||
6 | * Based on drivers/serial/s3c6400.c | ||
7 | * | ||
8 | * Driver for Samsung S5PV210 SoC UARTs. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/module.h> | ||
16 | #include <linux/ioport.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/serial_core.h> | ||
21 | #include <linux/serial.h> | ||
22 | |||
23 | #include <asm/irq.h> | ||
24 | #include <mach/hardware.h> | ||
25 | #include <plat/regs-serial.h> | ||
26 | #include "samsung.h" | ||
27 | |||
28 | static int s5pv210_serial_setsource(struct uart_port *port, | ||
29 | struct s3c24xx_uart_clksrc *clk) | ||
30 | { | ||
31 | struct s3c2410_uartcfg *cfg = port->dev->platform_data; | ||
32 | unsigned long ucon = rd_regl(port, S3C2410_UCON); | ||
33 | |||
34 | if ((cfg->clocks_size) == 1) | ||
35 | return 0; | ||
36 | |||
37 | if (strcmp(clk->name, "pclk") == 0) | ||
38 | ucon &= ~S5PV210_UCON_CLKMASK; | ||
39 | else if (strcmp(clk->name, "uclk1") == 0) | ||
40 | ucon |= S5PV210_UCON_CLKMASK; | ||
41 | else { | ||
42 | printk(KERN_ERR "unknown clock source %s\n", clk->name); | ||
43 | return -EINVAL; | ||
44 | } | ||
45 | |||
46 | wr_regl(port, S3C2410_UCON, ucon); | ||
47 | return 0; | ||
48 | } | ||
49 | |||
50 | |||
51 | static int s5pv210_serial_getsource(struct uart_port *port, | ||
52 | struct s3c24xx_uart_clksrc *clk) | ||
53 | { | ||
54 | struct s3c2410_uartcfg *cfg = port->dev->platform_data; | ||
55 | u32 ucon = rd_regl(port, S3C2410_UCON); | ||
56 | |||
57 | clk->divisor = 1; | ||
58 | |||
59 | if ((cfg->clocks_size) == 1) | ||
60 | return 0; | ||
61 | |||
62 | switch (ucon & S5PV210_UCON_CLKMASK) { | ||
63 | case S5PV210_UCON_PCLK: | ||
64 | clk->name = "pclk"; | ||
65 | break; | ||
66 | case S5PV210_UCON_UCLK: | ||
67 | clk->name = "uclk1"; | ||
68 | break; | ||
69 | } | ||
70 | |||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | static int s5pv210_serial_resetport(struct uart_port *port, | ||
75 | struct s3c2410_uartcfg *cfg) | ||
76 | { | ||
77 | unsigned long ucon = rd_regl(port, S3C2410_UCON); | ||
78 | |||
79 | ucon &= S5PV210_UCON_CLKMASK; | ||
80 | wr_regl(port, S3C2410_UCON, ucon | cfg->ucon); | ||
81 | wr_regl(port, S3C2410_ULCON, cfg->ulcon); | ||
82 | |||
83 | /* reset both fifos */ | ||
84 | wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH); | ||
85 | wr_regl(port, S3C2410_UFCON, cfg->ufcon); | ||
86 | |||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | #define S5PV210_UART_DEFAULT_INFO(fifo_size) \ | ||
91 | .name = "Samsung S5PV210 UART0", \ | ||
92 | .type = PORT_S3C6400, \ | ||
93 | .fifosize = fifo_size, \ | ||
94 | .has_divslot = 1, \ | ||
95 | .rx_fifomask = S5PV210_UFSTAT_RXMASK, \ | ||
96 | .rx_fifoshift = S5PV210_UFSTAT_RXSHIFT, \ | ||
97 | .rx_fifofull = S5PV210_UFSTAT_RXFULL, \ | ||
98 | .tx_fifofull = S5PV210_UFSTAT_TXFULL, \ | ||
99 | .tx_fifomask = S5PV210_UFSTAT_TXMASK, \ | ||
100 | .tx_fifoshift = S5PV210_UFSTAT_TXSHIFT, \ | ||
101 | .get_clksrc = s5pv210_serial_getsource, \ | ||
102 | .set_clksrc = s5pv210_serial_setsource, \ | ||
103 | .reset_port = s5pv210_serial_resetport | ||
104 | |||
105 | static struct s3c24xx_uart_info s5p_port_fifo256 = { | ||
106 | S5PV210_UART_DEFAULT_INFO(256), | ||
107 | }; | ||
108 | |||
109 | static struct s3c24xx_uart_info s5p_port_fifo64 = { | ||
110 | S5PV210_UART_DEFAULT_INFO(64), | ||
111 | }; | ||
112 | |||
113 | static struct s3c24xx_uart_info s5p_port_fifo16 = { | ||
114 | S5PV210_UART_DEFAULT_INFO(16), | ||
115 | }; | ||
116 | |||
117 | static struct s3c24xx_uart_info *s5p_uart_inf[] = { | ||
118 | [0] = &s5p_port_fifo256, | ||
119 | [1] = &s5p_port_fifo64, | ||
120 | [2] = &s5p_port_fifo16, | ||
121 | [3] = &s5p_port_fifo16, | ||
122 | }; | ||
123 | |||
124 | /* device management */ | ||
125 | static int s5p_serial_probe(struct platform_device *pdev) | ||
126 | { | ||
127 | return s3c24xx_serial_probe(pdev, s5p_uart_inf[pdev->id]); | ||
128 | } | ||
129 | |||
130 | static struct platform_driver s5p_serial_driver = { | ||
131 | .probe = s5p_serial_probe, | ||
132 | .remove = __devexit_p(s3c24xx_serial_remove), | ||
133 | .driver = { | ||
134 | .name = "s5pv210-uart", | ||
135 | .owner = THIS_MODULE, | ||
136 | }, | ||
137 | }; | ||
138 | |||
139 | static int __init s5pv210_serial_console_init(void) | ||
140 | { | ||
141 | return s3c24xx_serial_initconsole(&s5p_serial_driver, s5p_uart_inf); | ||
142 | } | ||
143 | |||
144 | console_initcall(s5pv210_serial_console_init); | ||
145 | |||
146 | static int __init s5p_serial_init(void) | ||
147 | { | ||
148 | return s3c24xx_serial_init(&s5p_serial_driver, *s5p_uart_inf); | ||
149 | } | ||
150 | |||
151 | static void __exit s5p_serial_exit(void) | ||
152 | { | ||
153 | platform_driver_unregister(&s5p_serial_driver); | ||
154 | } | ||
155 | |||
156 | module_init(s5p_serial_init); | ||
157 | module_exit(s5p_serial_exit); | ||
158 | |||
159 | MODULE_LICENSE("GPL"); | ||
160 | MODULE_ALIAS("platform:s5pv210-uart"); | ||
161 | MODULE_DESCRIPTION("Samsung S5PV210 UART Driver support"); | ||
162 | MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com>"); | ||
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c index 94530f01521e..2199d819a987 100644 --- a/drivers/serial/sa1100.c +++ b/drivers/serial/sa1100.c | |||
@@ -117,7 +117,7 @@ static void sa1100_mctrl_check(struct sa1100_port *sport) | |||
117 | if (changed & TIOCM_CTS) | 117 | if (changed & TIOCM_CTS) |
118 | uart_handle_cts_change(&sport->port, status & TIOCM_CTS); | 118 | uart_handle_cts_change(&sport->port, status & TIOCM_CTS); |
119 | 119 | ||
120 | wake_up_interruptible(&sport->port.info->delta_msr_wait); | 120 | wake_up_interruptible(&sport->port.state->port.delta_msr_wait); |
121 | } | 121 | } |
122 | 122 | ||
123 | /* | 123 | /* |
@@ -129,7 +129,7 @@ static void sa1100_timeout(unsigned long data) | |||
129 | struct sa1100_port *sport = (struct sa1100_port *)data; | 129 | struct sa1100_port *sport = (struct sa1100_port *)data; |
130 | unsigned long flags; | 130 | unsigned long flags; |
131 | 131 | ||
132 | if (sport->port.info) { | 132 | if (sport->port.state) { |
133 | spin_lock_irqsave(&sport->port.lock, flags); | 133 | spin_lock_irqsave(&sport->port.lock, flags); |
134 | sa1100_mctrl_check(sport); | 134 | sa1100_mctrl_check(sport); |
135 | spin_unlock_irqrestore(&sport->port.lock, flags); | 135 | spin_unlock_irqrestore(&sport->port.lock, flags); |
@@ -189,7 +189,7 @@ static void sa1100_enable_ms(struct uart_port *port) | |||
189 | static void | 189 | static void |
190 | sa1100_rx_chars(struct sa1100_port *sport) | 190 | sa1100_rx_chars(struct sa1100_port *sport) |
191 | { | 191 | { |
192 | struct tty_struct *tty = sport->port.info->port.tty; | 192 | struct tty_struct *tty = sport->port.state->port.tty; |
193 | unsigned int status, ch, flg; | 193 | unsigned int status, ch, flg; |
194 | 194 | ||
195 | status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) | | 195 | status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) | |
@@ -239,7 +239,7 @@ sa1100_rx_chars(struct sa1100_port *sport) | |||
239 | 239 | ||
240 | static void sa1100_tx_chars(struct sa1100_port *sport) | 240 | static void sa1100_tx_chars(struct sa1100_port *sport) |
241 | { | 241 | { |
242 | struct circ_buf *xmit = &sport->port.info->xmit; | 242 | struct circ_buf *xmit = &sport->port.state->xmit; |
243 | 243 | ||
244 | if (sport->port.x_char) { | 244 | if (sport->port.x_char) { |
245 | UART_PUT_CHAR(sport, sport->port.x_char); | 245 | UART_PUT_CHAR(sport, sport->port.x_char); |
@@ -638,7 +638,7 @@ static void __init sa1100_init_ports(void) | |||
638 | PPSR |= PPC_TXD1 | PPC_TXD3; | 638 | PPSR |= PPC_TXD1 | PPC_TXD3; |
639 | } | 639 | } |
640 | 640 | ||
641 | void __init sa1100_register_uart_fns(struct sa1100_port_fns *fns) | 641 | void __devinit sa1100_register_uart_fns(struct sa1100_port_fns *fns) |
642 | { | 642 | { |
643 | if (fns->get_mctrl) | 643 | if (fns->get_mctrl) |
644 | sa1100_pops.get_mctrl = fns->get_mctrl; | 644 | sa1100_pops.get_mctrl = fns->get_mctrl; |
diff --git a/drivers/serial/samsung.c b/drivers/serial/samsung.c index c8851a0db63a..7ac2bf5167cd 100644 --- a/drivers/serial/samsung.c +++ b/drivers/serial/samsung.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * | 2 | * |
3 | * Driver core for Samsung SoC onboard UARTs. | 3 | * Driver core for Samsung SoC onboard UARTs. |
4 | * | 4 | * |
5 | * Ben Dooks, Copyright (c) 2003-2005,2008 Simtec Electronics | 5 | * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics |
6 | * http://armlinux.simtec.co.uk/ | 6 | * http://armlinux.simtec.co.uk/ |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
@@ -196,7 +196,7 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id) | |||
196 | { | 196 | { |
197 | struct s3c24xx_uart_port *ourport = dev_id; | 197 | struct s3c24xx_uart_port *ourport = dev_id; |
198 | struct uart_port *port = &ourport->port; | 198 | struct uart_port *port = &ourport->port; |
199 | struct tty_struct *tty = port->info->port.tty; | 199 | struct tty_struct *tty = port->state->port.tty; |
200 | unsigned int ufcon, ch, flag, ufstat, uerstat; | 200 | unsigned int ufcon, ch, flag, ufstat, uerstat; |
201 | int max_count = 64; | 201 | int max_count = 64; |
202 | 202 | ||
@@ -281,7 +281,7 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id) | |||
281 | { | 281 | { |
282 | struct s3c24xx_uart_port *ourport = id; | 282 | struct s3c24xx_uart_port *ourport = id; |
283 | struct uart_port *port = &ourport->port; | 283 | struct uart_port *port = &ourport->port; |
284 | struct circ_buf *xmit = &port->info->xmit; | 284 | struct circ_buf *xmit = &port->state->xmit; |
285 | int count = 256; | 285 | int count = 256; |
286 | 286 | ||
287 | if (port->x_char) { | 287 | if (port->x_char) { |
@@ -705,8 +705,13 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, | |||
705 | if (ourport->info->has_divslot) { | 705 | if (ourport->info->has_divslot) { |
706 | unsigned int div = ourport->baudclk_rate / baud; | 706 | unsigned int div = ourport->baudclk_rate / baud; |
707 | 707 | ||
708 | udivslot = udivslot_table[div & 15]; | 708 | if (cfg->has_fracval) { |
709 | dbg("udivslot = %04x (div %d)\n", udivslot, div & 15); | 709 | udivslot = (div & 15); |
710 | dbg("fracval = %04x\n", udivslot); | ||
711 | } else { | ||
712 | udivslot = udivslot_table[div & 15]; | ||
713 | dbg("udivslot = %04x (div %d)\n", udivslot, div & 15); | ||
714 | } | ||
710 | } | 715 | } |
711 | 716 | ||
712 | switch (termios->c_cflag & CSIZE) { | 717 | switch (termios->c_cflag & CSIZE) { |
@@ -992,10 +997,10 @@ static int s3c24xx_serial_cpufreq_transition(struct notifier_block *nb, | |||
992 | struct ktermios *termios; | 997 | struct ktermios *termios; |
993 | struct tty_struct *tty; | 998 | struct tty_struct *tty; |
994 | 999 | ||
995 | if (uport->info == NULL) | 1000 | if (uport->state == NULL) |
996 | goto exit; | 1001 | goto exit; |
997 | 1002 | ||
998 | tty = uport->info->port.tty; | 1003 | tty = uport->state->port.tty; |
999 | 1004 | ||
1000 | if (tty == NULL) | 1005 | if (tty == NULL) |
1001 | goto exit; | 1006 | goto exit; |
@@ -1096,7 +1101,7 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, | |||
1096 | dbg("resource %p (%lx..%lx)\n", res, res->start, res->end); | 1101 | dbg("resource %p (%lx..%lx)\n", res, res->start, res->end); |
1097 | 1102 | ||
1098 | port->mapbase = res->start; | 1103 | port->mapbase = res->start; |
1099 | port->membase = S3C_VA_UART + res->start - (S3C_PA_UART & 0xfff00000); | 1104 | port->membase = S3C_VA_UART + (res->start & 0xfffff); |
1100 | ret = platform_get_irq(platdev, 0); | 1105 | ret = platform_get_irq(platdev, 0); |
1101 | if (ret < 0) | 1106 | if (ret < 0) |
1102 | port->irq = 0; | 1107 | port->irq = 0; |
@@ -1271,7 +1276,7 @@ s3c24xx_serial_console_txrdy(struct uart_port *port, unsigned int ufcon) | |||
1271 | unsigned long ufstat, utrstat; | 1276 | unsigned long ufstat, utrstat; |
1272 | 1277 | ||
1273 | if (ufcon & S3C2410_UFCON_FIFOMODE) { | 1278 | if (ufcon & S3C2410_UFCON_FIFOMODE) { |
1274 | /* fifo mode - check ammount of data in fifo registers... */ | 1279 | /* fifo mode - check amount of data in fifo registers... */ |
1275 | 1280 | ||
1276 | ufstat = rd_regl(port, S3C2410_UFSTAT); | 1281 | ufstat = rd_regl(port, S3C2410_UFSTAT); |
1277 | return (ufstat & info->tx_fifofull) ? 0 : 1; | 1282 | return (ufstat & info->tx_fifofull) ? 0 : 1; |
@@ -1374,7 +1379,7 @@ s3c24xx_serial_get_options(struct uart_port *port, int *baud, | |||
1374 | * data. | 1379 | * data. |
1375 | */ | 1380 | */ |
1376 | 1381 | ||
1377 | static int s3c24xx_serial_init_ports(struct s3c24xx_uart_info *info) | 1382 | static int s3c24xx_serial_init_ports(struct s3c24xx_uart_info **info) |
1378 | { | 1383 | { |
1379 | struct s3c24xx_uart_port *ptr = s3c24xx_serial_ports; | 1384 | struct s3c24xx_uart_port *ptr = s3c24xx_serial_ports; |
1380 | struct platform_device **platdev_ptr; | 1385 | struct platform_device **platdev_ptr; |
@@ -1385,7 +1390,7 @@ static int s3c24xx_serial_init_ports(struct s3c24xx_uart_info *info) | |||
1385 | platdev_ptr = s3c24xx_uart_devs; | 1390 | platdev_ptr = s3c24xx_uart_devs; |
1386 | 1391 | ||
1387 | for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++, ptr++, platdev_ptr++) { | 1392 | for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++, ptr++, platdev_ptr++) { |
1388 | s3c24xx_serial_init_port(ptr, info, *platdev_ptr); | 1393 | s3c24xx_serial_init_port(ptr, info[i], *platdev_ptr); |
1389 | } | 1394 | } |
1390 | 1395 | ||
1391 | return 0; | 1396 | return 0; |
@@ -1451,7 +1456,7 @@ static struct console s3c24xx_serial_console = { | |||
1451 | }; | 1456 | }; |
1452 | 1457 | ||
1453 | int s3c24xx_serial_initconsole(struct platform_driver *drv, | 1458 | int s3c24xx_serial_initconsole(struct platform_driver *drv, |
1454 | struct s3c24xx_uart_info *info) | 1459 | struct s3c24xx_uart_info **info) |
1455 | 1460 | ||
1456 | { | 1461 | { |
1457 | struct platform_device *dev = s3c24xx_uart_devs[0]; | 1462 | struct platform_device *dev = s3c24xx_uart_devs[0]; |
diff --git a/drivers/serial/samsung.h b/drivers/serial/samsung.h index d3fe315969f6..0ac06a07d25f 100644 --- a/drivers/serial/samsung.h +++ b/drivers/serial/samsung.h | |||
@@ -2,7 +2,7 @@ | |||
2 | * | 2 | * |
3 | * Driver for Samsung SoC onboard UARTs. | 3 | * Driver for Samsung SoC onboard UARTs. |
4 | * | 4 | * |
5 | * Ben Dooks, Copyright (c) 2003-2005,2008 Simtec Electronics | 5 | * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics |
6 | * http://armlinux.simtec.co.uk/ | 6 | * http://armlinux.simtec.co.uk/ |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
@@ -75,19 +75,24 @@ extern int s3c24xx_serial_probe(struct platform_device *dev, | |||
75 | extern int __devexit s3c24xx_serial_remove(struct platform_device *dev); | 75 | extern int __devexit s3c24xx_serial_remove(struct platform_device *dev); |
76 | 76 | ||
77 | extern int s3c24xx_serial_initconsole(struct platform_driver *drv, | 77 | extern int s3c24xx_serial_initconsole(struct platform_driver *drv, |
78 | struct s3c24xx_uart_info *uart); | 78 | struct s3c24xx_uart_info **uart); |
79 | 79 | ||
80 | extern int s3c24xx_serial_init(struct platform_driver *drv, | 80 | extern int s3c24xx_serial_init(struct platform_driver *drv, |
81 | struct s3c24xx_uart_info *info); | 81 | struct s3c24xx_uart_info *info); |
82 | 82 | ||
83 | #ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE | 83 | #ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE |
84 | 84 | ||
85 | #define s3c24xx_console_init(__drv, __inf) \ | 85 | #define s3c24xx_console_init(__drv, __inf) \ |
86 | static int __init s3c_serial_console_init(void) \ | 86 | static int __init s3c_serial_console_init(void) \ |
87 | { \ | 87 | { \ |
88 | return s3c24xx_serial_initconsole(__drv, __inf); \ | 88 | struct s3c24xx_uart_info *uinfo[CONFIG_SERIAL_SAMSUNG_UARTS]; \ |
89 | } \ | 89 | int i; \ |
90 | \ | 90 | \ |
91 | for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++) \ | ||
92 | uinfo[i] = __inf; \ | ||
93 | return s3c24xx_serial_initconsole(__drv, uinfo); \ | ||
94 | } \ | ||
95 | \ | ||
91 | console_initcall(s3c_serial_console_init) | 96 | console_initcall(s3c_serial_console_init) |
92 | 97 | ||
93 | #else | 98 | #else |
diff --git a/drivers/serial/sb1250-duart.c b/drivers/serial/sb1250-duart.c index 319e8b83f6be..a2f2b3254499 100644 --- a/drivers/serial/sb1250-duart.c +++ b/drivers/serial/sb1250-duart.c | |||
@@ -384,13 +384,13 @@ static void sbd_receive_chars(struct sbd_port *sport) | |||
384 | uart_insert_char(uport, status, M_DUART_OVRUN_ERR, ch, flag); | 384 | uart_insert_char(uport, status, M_DUART_OVRUN_ERR, ch, flag); |
385 | } | 385 | } |
386 | 386 | ||
387 | tty_flip_buffer_push(uport->info->port.tty); | 387 | tty_flip_buffer_push(uport->state->port.tty); |
388 | } | 388 | } |
389 | 389 | ||
390 | static void sbd_transmit_chars(struct sbd_port *sport) | 390 | static void sbd_transmit_chars(struct sbd_port *sport) |
391 | { | 391 | { |
392 | struct uart_port *uport = &sport->port; | 392 | struct uart_port *uport = &sport->port; |
393 | struct circ_buf *xmit = &sport->port.info->xmit; | 393 | struct circ_buf *xmit = &sport->port.state->xmit; |
394 | unsigned int mask; | 394 | unsigned int mask; |
395 | int stop_tx; | 395 | int stop_tx; |
396 | 396 | ||
@@ -440,7 +440,7 @@ static void sbd_status_handle(struct sbd_port *sport) | |||
440 | 440 | ||
441 | if (delta & ((M_DUART_IN_PIN2_VAL | M_DUART_IN_PIN0_VAL) << | 441 | if (delta & ((M_DUART_IN_PIN2_VAL | M_DUART_IN_PIN0_VAL) << |
442 | S_DUART_IN_PIN_CHNG)) | 442 | S_DUART_IN_PIN_CHNG)) |
443 | wake_up_interruptible(&uport->info->delta_msr_wait); | 443 | wake_up_interruptible(&uport->state->port.delta_msr_wait); |
444 | } | 444 | } |
445 | 445 | ||
446 | static irqreturn_t sbd_interrupt(int irq, void *dev_id) | 446 | static irqreturn_t sbd_interrupt(int irq, void *dev_id) |
diff --git a/drivers/serial/sc26xx.c b/drivers/serial/sc26xx.c index e0be11ceaa25..75038ad2b242 100644 --- a/drivers/serial/sc26xx.c +++ b/drivers/serial/sc26xx.c | |||
@@ -140,8 +140,8 @@ static struct tty_struct *receive_chars(struct uart_port *port) | |||
140 | char flag; | 140 | char flag; |
141 | u8 status; | 141 | u8 status; |
142 | 142 | ||
143 | if (port->info != NULL) /* Unopened serial console */ | 143 | if (port->state != NULL) /* Unopened serial console */ |
144 | tty = port->info->port.tty; | 144 | tty = port->state->port.tty; |
145 | 145 | ||
146 | while (limit-- > 0) { | 146 | while (limit-- > 0) { |
147 | status = READ_SC_PORT(port, SR); | 147 | status = READ_SC_PORT(port, SR); |
@@ -190,10 +190,10 @@ static void transmit_chars(struct uart_port *port) | |||
190 | { | 190 | { |
191 | struct circ_buf *xmit; | 191 | struct circ_buf *xmit; |
192 | 192 | ||
193 | if (!port->info) | 193 | if (!port->state) |
194 | return; | 194 | return; |
195 | 195 | ||
196 | xmit = &port->info->xmit; | 196 | xmit = &port->state->xmit; |
197 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { | 197 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { |
198 | sc26xx_disable_irq(port, IMR_TXRDY); | 198 | sc26xx_disable_irq(port, IMR_TXRDY); |
199 | return; | 199 | return; |
@@ -316,7 +316,7 @@ static void sc26xx_stop_tx(struct uart_port *port) | |||
316 | /* port->lock held by caller. */ | 316 | /* port->lock held by caller. */ |
317 | static void sc26xx_start_tx(struct uart_port *port) | 317 | static void sc26xx_start_tx(struct uart_port *port) |
318 | { | 318 | { |
319 | struct circ_buf *xmit = &port->info->xmit; | 319 | struct circ_buf *xmit = &port->state->xmit; |
320 | 320 | ||
321 | while (!uart_circ_empty(xmit)) { | 321 | while (!uart_circ_empty(xmit)) { |
322 | if (!(READ_SC_PORT(port, SR) & SR_TXRDY)) { | 322 | if (!(READ_SC_PORT(port, SR) & SR_TXRDY)) { |
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index b0bb29d804ae..460a72d91bb7 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c | |||
@@ -29,10 +29,9 @@ | |||
29 | #include <linux/console.h> | 29 | #include <linux/console.h> |
30 | #include <linux/proc_fs.h> | 30 | #include <linux/proc_fs.h> |
31 | #include <linux/seq_file.h> | 31 | #include <linux/seq_file.h> |
32 | #include <linux/serial_core.h> | ||
33 | #include <linux/smp_lock.h> | ||
34 | #include <linux/device.h> | 32 | #include <linux/device.h> |
35 | #include <linux/serial.h> /* for serial_state and serial_icounter_struct */ | 33 | #include <linux/serial.h> /* for serial_state and serial_icounter_struct */ |
34 | #include <linux/serial_core.h> | ||
36 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
37 | #include <linux/mutex.h> | 36 | #include <linux/mutex.h> |
38 | 37 | ||
@@ -52,17 +51,15 @@ static struct lock_class_key port_lock_key; | |||
52 | 51 | ||
53 | #define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) | 52 | #define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) |
54 | 53 | ||
55 | #define uart_users(state) ((state)->count + (state)->info.port.blocked_open) | ||
56 | |||
57 | #ifdef CONFIG_SERIAL_CORE_CONSOLE | 54 | #ifdef CONFIG_SERIAL_CORE_CONSOLE |
58 | #define uart_console(port) ((port)->cons && (port)->cons->index == (port)->line) | 55 | #define uart_console(port) ((port)->cons && (port)->cons->index == (port)->line) |
59 | #else | 56 | #else |
60 | #define uart_console(port) (0) | 57 | #define uart_console(port) (0) |
61 | #endif | 58 | #endif |
62 | 59 | ||
63 | static void uart_change_speed(struct uart_state *state, | 60 | static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, |
64 | struct ktermios *old_termios); | 61 | struct ktermios *old_termios); |
65 | static void uart_wait_until_sent(struct tty_struct *tty, int timeout); | 62 | static void __uart_wait_until_sent(struct uart_port *port, int timeout); |
66 | static void uart_change_pm(struct uart_state *state, int pm_state); | 63 | static void uart_change_pm(struct uart_state *state, int pm_state); |
67 | 64 | ||
68 | /* | 65 | /* |
@@ -71,19 +68,19 @@ static void uart_change_pm(struct uart_state *state, int pm_state); | |||
71 | */ | 68 | */ |
72 | void uart_write_wakeup(struct uart_port *port) | 69 | void uart_write_wakeup(struct uart_port *port) |
73 | { | 70 | { |
74 | struct uart_info *info = port->info; | 71 | struct uart_state *state = port->state; |
75 | /* | 72 | /* |
76 | * This means you called this function _after_ the port was | 73 | * This means you called this function _after_ the port was |
77 | * closed. No cookie for you. | 74 | * closed. No cookie for you. |
78 | */ | 75 | */ |
79 | BUG_ON(!info); | 76 | BUG_ON(!state); |
80 | tasklet_schedule(&info->tlet); | 77 | tasklet_schedule(&state->tlet); |
81 | } | 78 | } |
82 | 79 | ||
83 | static void uart_stop(struct tty_struct *tty) | 80 | static void uart_stop(struct tty_struct *tty) |
84 | { | 81 | { |
85 | struct uart_state *state = tty->driver_data; | 82 | struct uart_state *state = tty->driver_data; |
86 | struct uart_port *port = state->port; | 83 | struct uart_port *port = state->uart_port; |
87 | unsigned long flags; | 84 | unsigned long flags; |
88 | 85 | ||
89 | spin_lock_irqsave(&port->lock, flags); | 86 | spin_lock_irqsave(&port->lock, flags); |
@@ -94,9 +91,9 @@ static void uart_stop(struct tty_struct *tty) | |||
94 | static void __uart_start(struct tty_struct *tty) | 91 | static void __uart_start(struct tty_struct *tty) |
95 | { | 92 | { |
96 | struct uart_state *state = tty->driver_data; | 93 | struct uart_state *state = tty->driver_data; |
97 | struct uart_port *port = state->port; | 94 | struct uart_port *port = state->uart_port; |
98 | 95 | ||
99 | if (!uart_circ_empty(&state->info.xmit) && state->info.xmit.buf && | 96 | if (!uart_circ_empty(&state->xmit) && state->xmit.buf && |
100 | !tty->stopped && !tty->hw_stopped) | 97 | !tty->stopped && !tty->hw_stopped) |
101 | port->ops->start_tx(port); | 98 | port->ops->start_tx(port); |
102 | } | 99 | } |
@@ -104,7 +101,7 @@ static void __uart_start(struct tty_struct *tty) | |||
104 | static void uart_start(struct tty_struct *tty) | 101 | static void uart_start(struct tty_struct *tty) |
105 | { | 102 | { |
106 | struct uart_state *state = tty->driver_data; | 103 | struct uart_state *state = tty->driver_data; |
107 | struct uart_port *port = state->port; | 104 | struct uart_port *port = state->uart_port; |
108 | unsigned long flags; | 105 | unsigned long flags; |
109 | 106 | ||
110 | spin_lock_irqsave(&port->lock, flags); | 107 | spin_lock_irqsave(&port->lock, flags); |
@@ -115,7 +112,7 @@ static void uart_start(struct tty_struct *tty) | |||
115 | static void uart_tasklet_action(unsigned long data) | 112 | static void uart_tasklet_action(unsigned long data) |
116 | { | 113 | { |
117 | struct uart_state *state = (struct uart_state *)data; | 114 | struct uart_state *state = (struct uart_state *)data; |
118 | tty_wakeup(state->info.port.tty); | 115 | tty_wakeup(state->port.tty); |
119 | } | 116 | } |
120 | 117 | ||
121 | static inline void | 118 | static inline void |
@@ -139,14 +136,14 @@ uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear) | |||
139 | * Startup the port. This will be called once per open. All calls | 136 | * Startup the port. This will be called once per open. All calls |
140 | * will be serialised by the per-port mutex. | 137 | * will be serialised by the per-port mutex. |
141 | */ | 138 | */ |
142 | static int uart_startup(struct uart_state *state, int init_hw) | 139 | static int uart_startup(struct tty_struct *tty, struct uart_state *state, int init_hw) |
143 | { | 140 | { |
144 | struct uart_info *info = &state->info; | 141 | struct uart_port *uport = state->uart_port; |
145 | struct uart_port *port = state->port; | 142 | struct tty_port *port = &state->port; |
146 | unsigned long page; | 143 | unsigned long page; |
147 | int retval = 0; | 144 | int retval = 0; |
148 | 145 | ||
149 | if (info->flags & UIF_INITIALIZED) | 146 | if (port->flags & ASYNC_INITIALIZED) |
150 | return 0; | 147 | return 0; |
151 | 148 | ||
152 | /* | 149 | /* |
@@ -154,51 +151,51 @@ static int uart_startup(struct uart_state *state, int init_hw) | |||
154 | * once we have successfully opened the port. Also set | 151 | * once we have successfully opened the port. Also set |
155 | * up the tty->alt_speed kludge | 152 | * up the tty->alt_speed kludge |
156 | */ | 153 | */ |
157 | set_bit(TTY_IO_ERROR, &info->port.tty->flags); | 154 | set_bit(TTY_IO_ERROR, &tty->flags); |
158 | 155 | ||
159 | if (port->type == PORT_UNKNOWN) | 156 | if (uport->type == PORT_UNKNOWN) |
160 | return 0; | 157 | return 0; |
161 | 158 | ||
162 | /* | 159 | /* |
163 | * Initialise and allocate the transmit and temporary | 160 | * Initialise and allocate the transmit and temporary |
164 | * buffer. | 161 | * buffer. |
165 | */ | 162 | */ |
166 | if (!info->xmit.buf) { | 163 | if (!state->xmit.buf) { |
167 | /* This is protected by the per port mutex */ | 164 | /* This is protected by the per port mutex */ |
168 | page = get_zeroed_page(GFP_KERNEL); | 165 | page = get_zeroed_page(GFP_KERNEL); |
169 | if (!page) | 166 | if (!page) |
170 | return -ENOMEM; | 167 | return -ENOMEM; |
171 | 168 | ||
172 | info->xmit.buf = (unsigned char *) page; | 169 | state->xmit.buf = (unsigned char *) page; |
173 | uart_circ_clear(&info->xmit); | 170 | uart_circ_clear(&state->xmit); |
174 | } | 171 | } |
175 | 172 | ||
176 | retval = port->ops->startup(port); | 173 | retval = uport->ops->startup(uport); |
177 | if (retval == 0) { | 174 | if (retval == 0) { |
178 | if (init_hw) { | 175 | if (init_hw) { |
179 | /* | 176 | /* |
180 | * Initialise the hardware port settings. | 177 | * Initialise the hardware port settings. |
181 | */ | 178 | */ |
182 | uart_change_speed(state, NULL); | 179 | uart_change_speed(tty, state, NULL); |
183 | 180 | ||
184 | /* | 181 | /* |
185 | * Setup the RTS and DTR signals once the | 182 | * Setup the RTS and DTR signals once the |
186 | * port is open and ready to respond. | 183 | * port is open and ready to respond. |
187 | */ | 184 | */ |
188 | if (info->port.tty->termios->c_cflag & CBAUD) | 185 | if (tty->termios->c_cflag & CBAUD) |
189 | uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR); | 186 | uart_set_mctrl(uport, TIOCM_RTS | TIOCM_DTR); |
190 | } | 187 | } |
191 | 188 | ||
192 | if (info->flags & UIF_CTS_FLOW) { | 189 | if (port->flags & ASYNC_CTS_FLOW) { |
193 | spin_lock_irq(&port->lock); | 190 | spin_lock_irq(&uport->lock); |
194 | if (!(port->ops->get_mctrl(port) & TIOCM_CTS)) | 191 | if (!(uport->ops->get_mctrl(uport) & TIOCM_CTS)) |
195 | info->port.tty->hw_stopped = 1; | 192 | tty->hw_stopped = 1; |
196 | spin_unlock_irq(&port->lock); | 193 | spin_unlock_irq(&uport->lock); |
197 | } | 194 | } |
198 | 195 | ||
199 | info->flags |= UIF_INITIALIZED; | 196 | set_bit(ASYNCB_INITIALIZED, &port->flags); |
200 | 197 | ||
201 | clear_bit(TTY_IO_ERROR, &info->port.tty->flags); | 198 | clear_bit(TTY_IO_ERROR, &tty->flags); |
202 | } | 199 | } |
203 | 200 | ||
204 | if (retval && capable(CAP_SYS_ADMIN)) | 201 | if (retval && capable(CAP_SYS_ADMIN)) |
@@ -212,11 +209,10 @@ static int uart_startup(struct uart_state *state, int init_hw) | |||
212 | * DTR is dropped if the hangup on close termio flag is on. Calls to | 209 | * DTR is dropped if the hangup on close termio flag is on. Calls to |
213 | * uart_shutdown are serialised by the per-port semaphore. | 210 | * uart_shutdown are serialised by the per-port semaphore. |
214 | */ | 211 | */ |
215 | static void uart_shutdown(struct uart_state *state) | 212 | static void uart_shutdown(struct tty_struct *tty, struct uart_state *state) |
216 | { | 213 | { |
217 | struct uart_info *info = &state->info; | 214 | struct uart_port *uport = state->uart_port; |
218 | struct uart_port *port = state->port; | 215 | struct tty_port *port = &state->port; |
219 | struct tty_struct *tty = info->port.tty; | ||
220 | 216 | ||
221 | /* | 217 | /* |
222 | * Set the TTY IO error marker | 218 | * Set the TTY IO error marker |
@@ -224,14 +220,12 @@ static void uart_shutdown(struct uart_state *state) | |||
224 | if (tty) | 220 | if (tty) |
225 | set_bit(TTY_IO_ERROR, &tty->flags); | 221 | set_bit(TTY_IO_ERROR, &tty->flags); |
226 | 222 | ||
227 | if (info->flags & UIF_INITIALIZED) { | 223 | if (test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags)) { |
228 | info->flags &= ~UIF_INITIALIZED; | ||
229 | |||
230 | /* | 224 | /* |
231 | * Turn off DTR and RTS early. | 225 | * Turn off DTR and RTS early. |
232 | */ | 226 | */ |
233 | if (!tty || (tty->termios->c_cflag & HUPCL)) | 227 | if (!tty || (tty->termios->c_cflag & HUPCL)) |
234 | uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); | 228 | uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS); |
235 | 229 | ||
236 | /* | 230 | /* |
237 | * clear delta_msr_wait queue to avoid mem leaks: we may free | 231 | * clear delta_msr_wait queue to avoid mem leaks: we may free |
@@ -240,30 +234,30 @@ static void uart_shutdown(struct uart_state *state) | |||
240 | * any outstanding file descriptors should be pointing at | 234 | * any outstanding file descriptors should be pointing at |
241 | * hung_up_tty_fops now. | 235 | * hung_up_tty_fops now. |
242 | */ | 236 | */ |
243 | wake_up_interruptible(&info->delta_msr_wait); | 237 | wake_up_interruptible(&port->delta_msr_wait); |
244 | 238 | ||
245 | /* | 239 | /* |
246 | * Free the IRQ and disable the port. | 240 | * Free the IRQ and disable the port. |
247 | */ | 241 | */ |
248 | port->ops->shutdown(port); | 242 | uport->ops->shutdown(uport); |
249 | 243 | ||
250 | /* | 244 | /* |
251 | * Ensure that the IRQ handler isn't running on another CPU. | 245 | * Ensure that the IRQ handler isn't running on another CPU. |
252 | */ | 246 | */ |
253 | synchronize_irq(port->irq); | 247 | synchronize_irq(uport->irq); |
254 | } | 248 | } |
255 | 249 | ||
256 | /* | 250 | /* |
257 | * kill off our tasklet | 251 | * kill off our tasklet |
258 | */ | 252 | */ |
259 | tasklet_kill(&info->tlet); | 253 | tasklet_kill(&state->tlet); |
260 | 254 | ||
261 | /* | 255 | /* |
262 | * Free the transmit buffer page. | 256 | * Free the transmit buffer page. |
263 | */ | 257 | */ |
264 | if (info->xmit.buf) { | 258 | if (state->xmit.buf) { |
265 | free_page((unsigned long)info->xmit.buf); | 259 | free_page((unsigned long)state->xmit.buf); |
266 | info->xmit.buf = NULL; | 260 | state->xmit.buf = NULL; |
267 | } | 261 | } |
268 | } | 262 | } |
269 | 263 | ||
@@ -346,11 +340,11 @@ uart_get_baud_rate(struct uart_port *port, struct ktermios *termios, | |||
346 | 340 | ||
347 | if (flags == UPF_SPD_HI) | 341 | if (flags == UPF_SPD_HI) |
348 | altbaud = 57600; | 342 | altbaud = 57600; |
349 | if (flags == UPF_SPD_VHI) | 343 | else if (flags == UPF_SPD_VHI) |
350 | altbaud = 115200; | 344 | altbaud = 115200; |
351 | if (flags == UPF_SPD_SHI) | 345 | else if (flags == UPF_SPD_SHI) |
352 | altbaud = 230400; | 346 | altbaud = 230400; |
353 | if (flags == UPF_SPD_WARP) | 347 | else if (flags == UPF_SPD_WARP) |
354 | altbaud = 460800; | 348 | altbaud = 460800; |
355 | 349 | ||
356 | for (try = 0; try < 2; try++) { | 350 | for (try = 0; try < 2; try++) { |
@@ -389,13 +383,20 @@ uart_get_baud_rate(struct uart_port *port, struct ktermios *termios, | |||
389 | } | 383 | } |
390 | 384 | ||
391 | /* | 385 | /* |
392 | * As a last resort, if the quotient is zero, | 386 | * As a last resort, if the range cannot be met then clip to |
393 | * default to 9600 bps | 387 | * the nearest chip supported rate. |
394 | */ | 388 | */ |
395 | if (!hung_up) | 389 | if (!hung_up) { |
396 | tty_termios_encode_baud_rate(termios, 9600, 9600); | 390 | if (baud <= min) |
391 | tty_termios_encode_baud_rate(termios, | ||
392 | min + 1, min + 1); | ||
393 | else | ||
394 | tty_termios_encode_baud_rate(termios, | ||
395 | max - 1, max - 1); | ||
396 | } | ||
397 | } | 397 | } |
398 | 398 | /* Should never happen */ | |
399 | WARN_ON(1); | ||
399 | return 0; | 400 | return 0; |
400 | } | 401 | } |
401 | 402 | ||
@@ -427,18 +428,18 @@ uart_get_divisor(struct uart_port *port, unsigned int baud) | |||
427 | EXPORT_SYMBOL(uart_get_divisor); | 428 | EXPORT_SYMBOL(uart_get_divisor); |
428 | 429 | ||
429 | /* FIXME: Consistent locking policy */ | 430 | /* FIXME: Consistent locking policy */ |
430 | static void | 431 | static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, |
431 | uart_change_speed(struct uart_state *state, struct ktermios *old_termios) | 432 | struct ktermios *old_termios) |
432 | { | 433 | { |
433 | struct tty_struct *tty = state->info.port.tty; | 434 | struct tty_port *port = &state->port; |
434 | struct uart_port *port = state->port; | 435 | struct uart_port *uport = state->uart_port; |
435 | struct ktermios *termios; | 436 | struct ktermios *termios; |
436 | 437 | ||
437 | /* | 438 | /* |
438 | * If we have no tty, termios, or the port does not exist, | 439 | * If we have no tty, termios, or the port does not exist, |
439 | * then we can't set the parameters for this port. | 440 | * then we can't set the parameters for this port. |
440 | */ | 441 | */ |
441 | if (!tty || !tty->termios || port->type == PORT_UNKNOWN) | 442 | if (!tty || !tty->termios || uport->type == PORT_UNKNOWN) |
442 | return; | 443 | return; |
443 | 444 | ||
444 | termios = tty->termios; | 445 | termios = tty->termios; |
@@ -447,20 +448,20 @@ uart_change_speed(struct uart_state *state, struct ktermios *old_termios) | |||
447 | * Set flags based on termios cflag | 448 | * Set flags based on termios cflag |
448 | */ | 449 | */ |
449 | if (termios->c_cflag & CRTSCTS) | 450 | if (termios->c_cflag & CRTSCTS) |
450 | state->info.flags |= UIF_CTS_FLOW; | 451 | set_bit(ASYNCB_CTS_FLOW, &port->flags); |
451 | else | 452 | else |
452 | state->info.flags &= ~UIF_CTS_FLOW; | 453 | clear_bit(ASYNCB_CTS_FLOW, &port->flags); |
453 | 454 | ||
454 | if (termios->c_cflag & CLOCAL) | 455 | if (termios->c_cflag & CLOCAL) |
455 | state->info.flags &= ~UIF_CHECK_CD; | 456 | clear_bit(ASYNCB_CHECK_CD, &port->flags); |
456 | else | 457 | else |
457 | state->info.flags |= UIF_CHECK_CD; | 458 | set_bit(ASYNCB_CHECK_CD, &port->flags); |
458 | 459 | ||
459 | port->ops->set_termios(port, termios, old_termios); | 460 | uport->ops->set_termios(uport, termios, old_termios); |
460 | } | 461 | } |
461 | 462 | ||
462 | static inline int | 463 | static inline int __uart_put_char(struct uart_port *port, |
463 | __uart_put_char(struct uart_port *port, struct circ_buf *circ, unsigned char c) | 464 | struct circ_buf *circ, unsigned char c) |
464 | { | 465 | { |
465 | unsigned long flags; | 466 | unsigned long flags; |
466 | int ret = 0; | 467 | int ret = 0; |
@@ -482,7 +483,7 @@ static int uart_put_char(struct tty_struct *tty, unsigned char ch) | |||
482 | { | 483 | { |
483 | struct uart_state *state = tty->driver_data; | 484 | struct uart_state *state = tty->driver_data; |
484 | 485 | ||
485 | return __uart_put_char(state->port, &state->info.xmit, ch); | 486 | return __uart_put_char(state->uart_port, &state->xmit, ch); |
486 | } | 487 | } |
487 | 488 | ||
488 | static void uart_flush_chars(struct tty_struct *tty) | 489 | static void uart_flush_chars(struct tty_struct *tty) |
@@ -490,8 +491,8 @@ static void uart_flush_chars(struct tty_struct *tty) | |||
490 | uart_start(tty); | 491 | uart_start(tty); |
491 | } | 492 | } |
492 | 493 | ||
493 | static int | 494 | static int uart_write(struct tty_struct *tty, |
494 | uart_write(struct tty_struct *tty, const unsigned char *buf, int count) | 495 | const unsigned char *buf, int count) |
495 | { | 496 | { |
496 | struct uart_state *state = tty->driver_data; | 497 | struct uart_state *state = tty->driver_data; |
497 | struct uart_port *port; | 498 | struct uart_port *port; |
@@ -508,8 +509,8 @@ uart_write(struct tty_struct *tty, const unsigned char *buf, int count) | |||
508 | return -EL3HLT; | 509 | return -EL3HLT; |
509 | } | 510 | } |
510 | 511 | ||
511 | port = state->port; | 512 | port = state->uart_port; |
512 | circ = &state->info.xmit; | 513 | circ = &state->xmit; |
513 | 514 | ||
514 | if (!circ->buf) | 515 | if (!circ->buf) |
515 | return 0; | 516 | return 0; |
@@ -539,9 +540,9 @@ static int uart_write_room(struct tty_struct *tty) | |||
539 | unsigned long flags; | 540 | unsigned long flags; |
540 | int ret; | 541 | int ret; |
541 | 542 | ||
542 | spin_lock_irqsave(&state->port->lock, flags); | 543 | spin_lock_irqsave(&state->uart_port->lock, flags); |
543 | ret = uart_circ_chars_free(&state->info.xmit); | 544 | ret = uart_circ_chars_free(&state->xmit); |
544 | spin_unlock_irqrestore(&state->port->lock, flags); | 545 | spin_unlock_irqrestore(&state->uart_port->lock, flags); |
545 | return ret; | 546 | return ret; |
546 | } | 547 | } |
547 | 548 | ||
@@ -551,9 +552,9 @@ static int uart_chars_in_buffer(struct tty_struct *tty) | |||
551 | unsigned long flags; | 552 | unsigned long flags; |
552 | int ret; | 553 | int ret; |
553 | 554 | ||
554 | spin_lock_irqsave(&state->port->lock, flags); | 555 | spin_lock_irqsave(&state->uart_port->lock, flags); |
555 | ret = uart_circ_chars_pending(&state->info.xmit); | 556 | ret = uart_circ_chars_pending(&state->xmit); |
556 | spin_unlock_irqrestore(&state->port->lock, flags); | 557 | spin_unlock_irqrestore(&state->uart_port->lock, flags); |
557 | return ret; | 558 | return ret; |
558 | } | 559 | } |
559 | 560 | ||
@@ -572,11 +573,11 @@ static void uart_flush_buffer(struct tty_struct *tty) | |||
572 | return; | 573 | return; |
573 | } | 574 | } |
574 | 575 | ||
575 | port = state->port; | 576 | port = state->uart_port; |
576 | pr_debug("uart_flush_buffer(%d) called\n", tty->index); | 577 | pr_debug("uart_flush_buffer(%d) called\n", tty->index); |
577 | 578 | ||
578 | spin_lock_irqsave(&port->lock, flags); | 579 | spin_lock_irqsave(&port->lock, flags); |
579 | uart_circ_clear(&state->info.xmit); | 580 | uart_circ_clear(&state->xmit); |
580 | if (port->ops->flush_buffer) | 581 | if (port->ops->flush_buffer) |
581 | port->ops->flush_buffer(port); | 582 | port->ops->flush_buffer(port); |
582 | spin_unlock_irqrestore(&port->lock, flags); | 583 | spin_unlock_irqrestore(&port->lock, flags); |
@@ -590,7 +591,7 @@ static void uart_flush_buffer(struct tty_struct *tty) | |||
590 | static void uart_send_xchar(struct tty_struct *tty, char ch) | 591 | static void uart_send_xchar(struct tty_struct *tty, char ch) |
591 | { | 592 | { |
592 | struct uart_state *state = tty->driver_data; | 593 | struct uart_state *state = tty->driver_data; |
593 | struct uart_port *port = state->port; | 594 | struct uart_port *port = state->uart_port; |
594 | unsigned long flags; | 595 | unsigned long flags; |
595 | 596 | ||
596 | if (port->ops->send_xchar) | 597 | if (port->ops->send_xchar) |
@@ -613,13 +614,13 @@ static void uart_throttle(struct tty_struct *tty) | |||
613 | uart_send_xchar(tty, STOP_CHAR(tty)); | 614 | uart_send_xchar(tty, STOP_CHAR(tty)); |
614 | 615 | ||
615 | if (tty->termios->c_cflag & CRTSCTS) | 616 | if (tty->termios->c_cflag & CRTSCTS) |
616 | uart_clear_mctrl(state->port, TIOCM_RTS); | 617 | uart_clear_mctrl(state->uart_port, TIOCM_RTS); |
617 | } | 618 | } |
618 | 619 | ||
619 | static void uart_unthrottle(struct tty_struct *tty) | 620 | static void uart_unthrottle(struct tty_struct *tty) |
620 | { | 621 | { |
621 | struct uart_state *state = tty->driver_data; | 622 | struct uart_state *state = tty->driver_data; |
622 | struct uart_port *port = state->port; | 623 | struct uart_port *port = state->uart_port; |
623 | 624 | ||
624 | if (I_IXOFF(tty)) { | 625 | if (I_IXOFF(tty)) { |
625 | if (port->x_char) | 626 | if (port->x_char) |
@@ -635,46 +636,48 @@ static void uart_unthrottle(struct tty_struct *tty) | |||
635 | static int uart_get_info(struct uart_state *state, | 636 | static int uart_get_info(struct uart_state *state, |
636 | struct serial_struct __user *retinfo) | 637 | struct serial_struct __user *retinfo) |
637 | { | 638 | { |
638 | struct uart_port *port = state->port; | 639 | struct uart_port *uport = state->uart_port; |
640 | struct tty_port *port = &state->port; | ||
639 | struct serial_struct tmp; | 641 | struct serial_struct tmp; |
640 | 642 | ||
641 | memset(&tmp, 0, sizeof(tmp)); | 643 | memset(&tmp, 0, sizeof(tmp)); |
642 | 644 | ||
643 | /* Ensure the state we copy is consistent and no hardware changes | 645 | /* Ensure the state we copy is consistent and no hardware changes |
644 | occur as we go */ | 646 | occur as we go */ |
645 | mutex_lock(&state->mutex); | 647 | mutex_lock(&port->mutex); |
646 | 648 | ||
647 | tmp.type = port->type; | 649 | tmp.type = uport->type; |
648 | tmp.line = port->line; | 650 | tmp.line = uport->line; |
649 | tmp.port = port->iobase; | 651 | tmp.port = uport->iobase; |
650 | if (HIGH_BITS_OFFSET) | 652 | if (HIGH_BITS_OFFSET) |
651 | tmp.port_high = (long) port->iobase >> HIGH_BITS_OFFSET; | 653 | tmp.port_high = (long) uport->iobase >> HIGH_BITS_OFFSET; |
652 | tmp.irq = port->irq; | 654 | tmp.irq = uport->irq; |
653 | tmp.flags = port->flags; | 655 | tmp.flags = uport->flags; |
654 | tmp.xmit_fifo_size = port->fifosize; | 656 | tmp.xmit_fifo_size = uport->fifosize; |
655 | tmp.baud_base = port->uartclk / 16; | 657 | tmp.baud_base = uport->uartclk / 16; |
656 | tmp.close_delay = state->close_delay / 10; | 658 | tmp.close_delay = port->close_delay / 10; |
657 | tmp.closing_wait = state->closing_wait == USF_CLOSING_WAIT_NONE ? | 659 | tmp.closing_wait = port->closing_wait == ASYNC_CLOSING_WAIT_NONE ? |
658 | ASYNC_CLOSING_WAIT_NONE : | 660 | ASYNC_CLOSING_WAIT_NONE : |
659 | state->closing_wait / 10; | 661 | port->closing_wait / 10; |
660 | tmp.custom_divisor = port->custom_divisor; | 662 | tmp.custom_divisor = uport->custom_divisor; |
661 | tmp.hub6 = port->hub6; | 663 | tmp.hub6 = uport->hub6; |
662 | tmp.io_type = port->iotype; | 664 | tmp.io_type = uport->iotype; |
663 | tmp.iomem_reg_shift = port->regshift; | 665 | tmp.iomem_reg_shift = uport->regshift; |
664 | tmp.iomem_base = (void *)(unsigned long)port->mapbase; | 666 | tmp.iomem_base = (void *)(unsigned long)uport->mapbase; |
665 | 667 | ||
666 | mutex_unlock(&state->mutex); | 668 | mutex_unlock(&port->mutex); |
667 | 669 | ||
668 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) | 670 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) |
669 | return -EFAULT; | 671 | return -EFAULT; |
670 | return 0; | 672 | return 0; |
671 | } | 673 | } |
672 | 674 | ||
673 | static int uart_set_info(struct uart_state *state, | 675 | static int uart_set_info(struct tty_struct *tty, struct uart_state *state, |
674 | struct serial_struct __user *newinfo) | 676 | struct serial_struct __user *newinfo) |
675 | { | 677 | { |
676 | struct serial_struct new_serial; | 678 | struct serial_struct new_serial; |
677 | struct uart_port *port = state->port; | 679 | struct uart_port *uport = state->uart_port; |
680 | struct tty_port *port = &state->port; | ||
678 | unsigned long new_port; | 681 | unsigned long new_port; |
679 | unsigned int change_irq, change_port, closing_wait; | 682 | unsigned int change_irq, change_port, closing_wait; |
680 | unsigned int old_custom_divisor, close_delay; | 683 | unsigned int old_custom_divisor, close_delay; |
@@ -691,58 +694,58 @@ static int uart_set_info(struct uart_state *state, | |||
691 | new_serial.irq = irq_canonicalize(new_serial.irq); | 694 | new_serial.irq = irq_canonicalize(new_serial.irq); |
692 | close_delay = new_serial.close_delay * 10; | 695 | close_delay = new_serial.close_delay * 10; |
693 | closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ? | 696 | closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ? |
694 | USF_CLOSING_WAIT_NONE : new_serial.closing_wait * 10; | 697 | ASYNC_CLOSING_WAIT_NONE : new_serial.closing_wait * 10; |
695 | 698 | ||
696 | /* | 699 | /* |
697 | * This semaphore protects state->count. It is also | 700 | * This semaphore protects port->count. It is also |
698 | * very useful to prevent opens. Also, take the | 701 | * very useful to prevent opens. Also, take the |
699 | * port configuration semaphore to make sure that a | 702 | * port configuration semaphore to make sure that a |
700 | * module insertion/removal doesn't change anything | 703 | * module insertion/removal doesn't change anything |
701 | * under us. | 704 | * under us. |
702 | */ | 705 | */ |
703 | mutex_lock(&state->mutex); | 706 | mutex_lock(&port->mutex); |
704 | 707 | ||
705 | change_irq = !(port->flags & UPF_FIXED_PORT) | 708 | change_irq = !(uport->flags & UPF_FIXED_PORT) |
706 | && new_serial.irq != port->irq; | 709 | && new_serial.irq != uport->irq; |
707 | 710 | ||
708 | /* | 711 | /* |
709 | * Since changing the 'type' of the port changes its resource | 712 | * Since changing the 'type' of the port changes its resource |
710 | * allocations, we should treat type changes the same as | 713 | * allocations, we should treat type changes the same as |
711 | * IO port changes. | 714 | * IO port changes. |
712 | */ | 715 | */ |
713 | change_port = !(port->flags & UPF_FIXED_PORT) | 716 | change_port = !(uport->flags & UPF_FIXED_PORT) |
714 | && (new_port != port->iobase || | 717 | && (new_port != uport->iobase || |
715 | (unsigned long)new_serial.iomem_base != port->mapbase || | 718 | (unsigned long)new_serial.iomem_base != uport->mapbase || |
716 | new_serial.hub6 != port->hub6 || | 719 | new_serial.hub6 != uport->hub6 || |
717 | new_serial.io_type != port->iotype || | 720 | new_serial.io_type != uport->iotype || |
718 | new_serial.iomem_reg_shift != port->regshift || | 721 | new_serial.iomem_reg_shift != uport->regshift || |
719 | new_serial.type != port->type); | 722 | new_serial.type != uport->type); |
720 | 723 | ||
721 | old_flags = port->flags; | 724 | old_flags = uport->flags; |
722 | new_flags = new_serial.flags; | 725 | new_flags = new_serial.flags; |
723 | old_custom_divisor = port->custom_divisor; | 726 | old_custom_divisor = uport->custom_divisor; |
724 | 727 | ||
725 | if (!capable(CAP_SYS_ADMIN)) { | 728 | if (!capable(CAP_SYS_ADMIN)) { |
726 | retval = -EPERM; | 729 | retval = -EPERM; |
727 | if (change_irq || change_port || | 730 | if (change_irq || change_port || |
728 | (new_serial.baud_base != port->uartclk / 16) || | 731 | (new_serial.baud_base != uport->uartclk / 16) || |
729 | (close_delay != state->close_delay) || | 732 | (close_delay != port->close_delay) || |
730 | (closing_wait != state->closing_wait) || | 733 | (closing_wait != port->closing_wait) || |
731 | (new_serial.xmit_fifo_size && | 734 | (new_serial.xmit_fifo_size && |
732 | new_serial.xmit_fifo_size != port->fifosize) || | 735 | new_serial.xmit_fifo_size != uport->fifosize) || |
733 | (((new_flags ^ old_flags) & ~UPF_USR_MASK) != 0)) | 736 | (((new_flags ^ old_flags) & ~UPF_USR_MASK) != 0)) |
734 | goto exit; | 737 | goto exit; |
735 | port->flags = ((port->flags & ~UPF_USR_MASK) | | 738 | uport->flags = ((uport->flags & ~UPF_USR_MASK) | |
736 | (new_flags & UPF_USR_MASK)); | 739 | (new_flags & UPF_USR_MASK)); |
737 | port->custom_divisor = new_serial.custom_divisor; | 740 | uport->custom_divisor = new_serial.custom_divisor; |
738 | goto check_and_exit; | 741 | goto check_and_exit; |
739 | } | 742 | } |
740 | 743 | ||
741 | /* | 744 | /* |
742 | * Ask the low level driver to verify the settings. | 745 | * Ask the low level driver to verify the settings. |
743 | */ | 746 | */ |
744 | if (port->ops->verify_port) | 747 | if (uport->ops->verify_port) |
745 | retval = port->ops->verify_port(port, &new_serial); | 748 | retval = uport->ops->verify_port(uport, &new_serial); |
746 | 749 | ||
747 | if ((new_serial.irq >= nr_irqs) || (new_serial.irq < 0) || | 750 | if ((new_serial.irq >= nr_irqs) || (new_serial.irq < 0) || |
748 | (new_serial.baud_base < 9600)) | 751 | (new_serial.baud_base < 9600)) |
@@ -757,45 +760,45 @@ static int uart_set_info(struct uart_state *state, | |||
757 | /* | 760 | /* |
758 | * Make sure that we are the sole user of this port. | 761 | * Make sure that we are the sole user of this port. |
759 | */ | 762 | */ |
760 | if (uart_users(state) > 1) | 763 | if (tty_port_users(port) > 1) |
761 | goto exit; | 764 | goto exit; |
762 | 765 | ||
763 | /* | 766 | /* |
764 | * We need to shutdown the serial port at the old | 767 | * We need to shutdown the serial port at the old |
765 | * port/type/irq combination. | 768 | * port/type/irq combination. |
766 | */ | 769 | */ |
767 | uart_shutdown(state); | 770 | uart_shutdown(tty, state); |
768 | } | 771 | } |
769 | 772 | ||
770 | if (change_port) { | 773 | if (change_port) { |
771 | unsigned long old_iobase, old_mapbase; | 774 | unsigned long old_iobase, old_mapbase; |
772 | unsigned int old_type, old_iotype, old_hub6, old_shift; | 775 | unsigned int old_type, old_iotype, old_hub6, old_shift; |
773 | 776 | ||
774 | old_iobase = port->iobase; | 777 | old_iobase = uport->iobase; |
775 | old_mapbase = port->mapbase; | 778 | old_mapbase = uport->mapbase; |
776 | old_type = port->type; | 779 | old_type = uport->type; |
777 | old_hub6 = port->hub6; | 780 | old_hub6 = uport->hub6; |
778 | old_iotype = port->iotype; | 781 | old_iotype = uport->iotype; |
779 | old_shift = port->regshift; | 782 | old_shift = uport->regshift; |
780 | 783 | ||
781 | /* | 784 | /* |
782 | * Free and release old regions | 785 | * Free and release old regions |
783 | */ | 786 | */ |
784 | if (old_type != PORT_UNKNOWN) | 787 | if (old_type != PORT_UNKNOWN) |
785 | port->ops->release_port(port); | 788 | uport->ops->release_port(uport); |
786 | 789 | ||
787 | port->iobase = new_port; | 790 | uport->iobase = new_port; |
788 | port->type = new_serial.type; | 791 | uport->type = new_serial.type; |
789 | port->hub6 = new_serial.hub6; | 792 | uport->hub6 = new_serial.hub6; |
790 | port->iotype = new_serial.io_type; | 793 | uport->iotype = new_serial.io_type; |
791 | port->regshift = new_serial.iomem_reg_shift; | 794 | uport->regshift = new_serial.iomem_reg_shift; |
792 | port->mapbase = (unsigned long)new_serial.iomem_base; | 795 | uport->mapbase = (unsigned long)new_serial.iomem_base; |
793 | 796 | ||
794 | /* | 797 | /* |
795 | * Claim and map the new regions | 798 | * Claim and map the new regions |
796 | */ | 799 | */ |
797 | if (port->type != PORT_UNKNOWN) { | 800 | if (uport->type != PORT_UNKNOWN) { |
798 | retval = port->ops->request_port(port); | 801 | retval = uport->ops->request_port(uport); |
799 | } else { | 802 | } else { |
800 | /* Always success - Jean II */ | 803 | /* Always success - Jean II */ |
801 | retval = 0; | 804 | retval = 0; |
@@ -806,19 +809,19 @@ static int uart_set_info(struct uart_state *state, | |||
806 | * new port, try to restore the old settings. | 809 | * new port, try to restore the old settings. |
807 | */ | 810 | */ |
808 | if (retval && old_type != PORT_UNKNOWN) { | 811 | if (retval && old_type != PORT_UNKNOWN) { |
809 | port->iobase = old_iobase; | 812 | uport->iobase = old_iobase; |
810 | port->type = old_type; | 813 | uport->type = old_type; |
811 | port->hub6 = old_hub6; | 814 | uport->hub6 = old_hub6; |
812 | port->iotype = old_iotype; | 815 | uport->iotype = old_iotype; |
813 | port->regshift = old_shift; | 816 | uport->regshift = old_shift; |
814 | port->mapbase = old_mapbase; | 817 | uport->mapbase = old_mapbase; |
815 | retval = port->ops->request_port(port); | 818 | retval = uport->ops->request_port(uport); |
816 | /* | 819 | /* |
817 | * If we failed to restore the old settings, | 820 | * If we failed to restore the old settings, |
818 | * we fail like this. | 821 | * we fail like this. |
819 | */ | 822 | */ |
820 | if (retval) | 823 | if (retval) |
821 | port->type = PORT_UNKNOWN; | 824 | uport->type = PORT_UNKNOWN; |
822 | 825 | ||
823 | /* | 826 | /* |
824 | * We failed anyway. | 827 | * We failed anyway. |
@@ -830,60 +833,63 @@ static int uart_set_info(struct uart_state *state, | |||
830 | } | 833 | } |
831 | 834 | ||
832 | if (change_irq) | 835 | if (change_irq) |
833 | port->irq = new_serial.irq; | 836 | uport->irq = new_serial.irq; |
834 | if (!(port->flags & UPF_FIXED_PORT)) | 837 | if (!(uport->flags & UPF_FIXED_PORT)) |
835 | port->uartclk = new_serial.baud_base * 16; | 838 | uport->uartclk = new_serial.baud_base * 16; |
836 | port->flags = (port->flags & ~UPF_CHANGE_MASK) | | 839 | uport->flags = (uport->flags & ~UPF_CHANGE_MASK) | |
837 | (new_flags & UPF_CHANGE_MASK); | 840 | (new_flags & UPF_CHANGE_MASK); |
838 | port->custom_divisor = new_serial.custom_divisor; | 841 | uport->custom_divisor = new_serial.custom_divisor; |
839 | state->close_delay = close_delay; | 842 | port->close_delay = close_delay; |
840 | state->closing_wait = closing_wait; | 843 | port->closing_wait = closing_wait; |
841 | if (new_serial.xmit_fifo_size) | 844 | if (new_serial.xmit_fifo_size) |
842 | port->fifosize = new_serial.xmit_fifo_size; | 845 | uport->fifosize = new_serial.xmit_fifo_size; |
843 | if (state->info.port.tty) | 846 | if (port->tty) |
844 | state->info.port.tty->low_latency = | 847 | port->tty->low_latency = |
845 | (port->flags & UPF_LOW_LATENCY) ? 1 : 0; | 848 | (uport->flags & UPF_LOW_LATENCY) ? 1 : 0; |
846 | 849 | ||
847 | check_and_exit: | 850 | check_and_exit: |
848 | retval = 0; | 851 | retval = 0; |
849 | if (port->type == PORT_UNKNOWN) | 852 | if (uport->type == PORT_UNKNOWN) |
850 | goto exit; | 853 | goto exit; |
851 | if (state->info.flags & UIF_INITIALIZED) { | 854 | if (port->flags & ASYNC_INITIALIZED) { |
852 | if (((old_flags ^ port->flags) & UPF_SPD_MASK) || | 855 | if (((old_flags ^ uport->flags) & UPF_SPD_MASK) || |
853 | old_custom_divisor != port->custom_divisor) { | 856 | old_custom_divisor != uport->custom_divisor) { |
854 | /* | 857 | /* |
855 | * If they're setting up a custom divisor or speed, | 858 | * If they're setting up a custom divisor or speed, |
856 | * instead of clearing it, then bitch about it. No | 859 | * instead of clearing it, then bitch about it. No |
857 | * need to rate-limit; it's CAP_SYS_ADMIN only. | 860 | * need to rate-limit; it's CAP_SYS_ADMIN only. |
858 | */ | 861 | */ |
859 | if (port->flags & UPF_SPD_MASK) { | 862 | if (uport->flags & UPF_SPD_MASK) { |
860 | char buf[64]; | 863 | char buf[64]; |
861 | printk(KERN_NOTICE | 864 | printk(KERN_NOTICE |
862 | "%s sets custom speed on %s. This " | 865 | "%s sets custom speed on %s. This " |
863 | "is deprecated.\n", current->comm, | 866 | "is deprecated.\n", current->comm, |
864 | tty_name(state->info.port.tty, buf)); | 867 | tty_name(port->tty, buf)); |
865 | } | 868 | } |
866 | uart_change_speed(state, NULL); | 869 | uart_change_speed(tty, state, NULL); |
867 | } | 870 | } |
868 | } else | 871 | } else |
869 | retval = uart_startup(state, 1); | 872 | retval = uart_startup(tty, state, 1); |
870 | exit: | 873 | exit: |
871 | mutex_unlock(&state->mutex); | 874 | mutex_unlock(&port->mutex); |
872 | return retval; | 875 | return retval; |
873 | } | 876 | } |
874 | 877 | ||
875 | 878 | /** | |
876 | /* | 879 | * uart_get_lsr_info - get line status register info |
877 | * uart_get_lsr_info - get line status register info. | 880 | * @tty: tty associated with the UART |
878 | * Note: uart_ioctl protects us against hangups. | 881 | * @state: UART being queried |
882 | * @value: returned modem value | ||
883 | * | ||
884 | * Note: uart_ioctl protects us against hangups. | ||
879 | */ | 885 | */ |
880 | static int uart_get_lsr_info(struct uart_state *state, | 886 | static int uart_get_lsr_info(struct tty_struct *tty, |
881 | unsigned int __user *value) | 887 | struct uart_state *state, unsigned int __user *value) |
882 | { | 888 | { |
883 | struct uart_port *port = state->port; | 889 | struct uart_port *uport = state->uart_port; |
884 | unsigned int result; | 890 | unsigned int result; |
885 | 891 | ||
886 | result = port->ops->tx_empty(port); | 892 | result = uport->ops->tx_empty(uport); |
887 | 893 | ||
888 | /* | 894 | /* |
889 | * If we're about to load something into the transmit | 895 | * If we're about to load something into the transmit |
@@ -891,9 +897,9 @@ static int uart_get_lsr_info(struct uart_state *state, | |||
891 | * avoid a race condition (depending on when the transmit | 897 | * avoid a race condition (depending on when the transmit |
892 | * interrupt happens). | 898 | * interrupt happens). |
893 | */ | 899 | */ |
894 | if (port->x_char || | 900 | if (uport->x_char || |
895 | ((uart_circ_chars_pending(&state->info.xmit) > 0) && | 901 | ((uart_circ_chars_pending(&state->xmit) > 0) && |
896 | !state->info.port.tty->stopped && !state->info.port.tty->hw_stopped)) | 902 | !tty->stopped && !tty->hw_stopped)) |
897 | result &= ~TIOCSER_TEMT; | 903 | result &= ~TIOCSER_TEMT; |
898 | 904 | ||
899 | return put_user(result, value); | 905 | return put_user(result, value); |
@@ -902,19 +908,20 @@ static int uart_get_lsr_info(struct uart_state *state, | |||
902 | static int uart_tiocmget(struct tty_struct *tty, struct file *file) | 908 | static int uart_tiocmget(struct tty_struct *tty, struct file *file) |
903 | { | 909 | { |
904 | struct uart_state *state = tty->driver_data; | 910 | struct uart_state *state = tty->driver_data; |
905 | struct uart_port *port = state->port; | 911 | struct tty_port *port = &state->port; |
912 | struct uart_port *uport = state->uart_port; | ||
906 | int result = -EIO; | 913 | int result = -EIO; |
907 | 914 | ||
908 | mutex_lock(&state->mutex); | 915 | mutex_lock(&port->mutex); |
909 | if ((!file || !tty_hung_up_p(file)) && | 916 | if ((!file || !tty_hung_up_p(file)) && |
910 | !(tty->flags & (1 << TTY_IO_ERROR))) { | 917 | !(tty->flags & (1 << TTY_IO_ERROR))) { |
911 | result = port->mctrl; | 918 | result = uport->mctrl; |
912 | 919 | ||
913 | spin_lock_irq(&port->lock); | 920 | spin_lock_irq(&uport->lock); |
914 | result |= port->ops->get_mctrl(port); | 921 | result |= uport->ops->get_mctrl(uport); |
915 | spin_unlock_irq(&port->lock); | 922 | spin_unlock_irq(&uport->lock); |
916 | } | 923 | } |
917 | mutex_unlock(&state->mutex); | 924 | mutex_unlock(&port->mutex); |
918 | 925 | ||
919 | return result; | 926 | return result; |
920 | } | 927 | } |
@@ -924,36 +931,39 @@ uart_tiocmset(struct tty_struct *tty, struct file *file, | |||
924 | unsigned int set, unsigned int clear) | 931 | unsigned int set, unsigned int clear) |
925 | { | 932 | { |
926 | struct uart_state *state = tty->driver_data; | 933 | struct uart_state *state = tty->driver_data; |
927 | struct uart_port *port = state->port; | 934 | struct uart_port *uport = state->uart_port; |
935 | struct tty_port *port = &state->port; | ||
928 | int ret = -EIO; | 936 | int ret = -EIO; |
929 | 937 | ||
930 | mutex_lock(&state->mutex); | 938 | mutex_lock(&port->mutex); |
931 | if ((!file || !tty_hung_up_p(file)) && | 939 | if ((!file || !tty_hung_up_p(file)) && |
932 | !(tty->flags & (1 << TTY_IO_ERROR))) { | 940 | !(tty->flags & (1 << TTY_IO_ERROR))) { |
933 | uart_update_mctrl(port, set, clear); | 941 | uart_update_mctrl(uport, set, clear); |
934 | ret = 0; | 942 | ret = 0; |
935 | } | 943 | } |
936 | mutex_unlock(&state->mutex); | 944 | mutex_unlock(&port->mutex); |
937 | return ret; | 945 | return ret; |
938 | } | 946 | } |
939 | 947 | ||
940 | static int uart_break_ctl(struct tty_struct *tty, int break_state) | 948 | static int uart_break_ctl(struct tty_struct *tty, int break_state) |
941 | { | 949 | { |
942 | struct uart_state *state = tty->driver_data; | 950 | struct uart_state *state = tty->driver_data; |
943 | struct uart_port *port = state->port; | 951 | struct tty_port *port = &state->port; |
952 | struct uart_port *uport = state->uart_port; | ||
944 | 953 | ||
945 | mutex_lock(&state->mutex); | 954 | mutex_lock(&port->mutex); |
946 | 955 | ||
947 | if (port->type != PORT_UNKNOWN) | 956 | if (uport->type != PORT_UNKNOWN) |
948 | port->ops->break_ctl(port, break_state); | 957 | uport->ops->break_ctl(uport, break_state); |
949 | 958 | ||
950 | mutex_unlock(&state->mutex); | 959 | mutex_unlock(&port->mutex); |
951 | return 0; | 960 | return 0; |
952 | } | 961 | } |
953 | 962 | ||
954 | static int uart_do_autoconfig(struct uart_state *state) | 963 | static int uart_do_autoconfig(struct tty_struct *tty,struct uart_state *state) |
955 | { | 964 | { |
956 | struct uart_port *port = state->port; | 965 | struct uart_port *uport = state->uart_port; |
966 | struct tty_port *port = &state->port; | ||
957 | int flags, ret; | 967 | int flags, ret; |
958 | 968 | ||
959 | if (!capable(CAP_SYS_ADMIN)) | 969 | if (!capable(CAP_SYS_ADMIN)) |
@@ -964,33 +974,33 @@ static int uart_do_autoconfig(struct uart_state *state) | |||
964 | * changing, and hence any extra opens of the port while | 974 | * changing, and hence any extra opens of the port while |
965 | * we're auto-configuring. | 975 | * we're auto-configuring. |
966 | */ | 976 | */ |
967 | if (mutex_lock_interruptible(&state->mutex)) | 977 | if (mutex_lock_interruptible(&port->mutex)) |
968 | return -ERESTARTSYS; | 978 | return -ERESTARTSYS; |
969 | 979 | ||
970 | ret = -EBUSY; | 980 | ret = -EBUSY; |
971 | if (uart_users(state) == 1) { | 981 | if (tty_port_users(port) == 1) { |
972 | uart_shutdown(state); | 982 | uart_shutdown(tty, state); |
973 | 983 | ||
974 | /* | 984 | /* |
975 | * If we already have a port type configured, | 985 | * If we already have a port type configured, |
976 | * we must release its resources. | 986 | * we must release its resources. |
977 | */ | 987 | */ |
978 | if (port->type != PORT_UNKNOWN) | 988 | if (uport->type != PORT_UNKNOWN) |
979 | port->ops->release_port(port); | 989 | uport->ops->release_port(uport); |
980 | 990 | ||
981 | flags = UART_CONFIG_TYPE; | 991 | flags = UART_CONFIG_TYPE; |
982 | if (port->flags & UPF_AUTO_IRQ) | 992 | if (uport->flags & UPF_AUTO_IRQ) |
983 | flags |= UART_CONFIG_IRQ; | 993 | flags |= UART_CONFIG_IRQ; |
984 | 994 | ||
985 | /* | 995 | /* |
986 | * This will claim the ports resources if | 996 | * This will claim the ports resources if |
987 | * a port is found. | 997 | * a port is found. |
988 | */ | 998 | */ |
989 | port->ops->config_port(port, flags); | 999 | uport->ops->config_port(uport, flags); |
990 | 1000 | ||
991 | ret = uart_startup(state, 1); | 1001 | ret = uart_startup(tty, state, 1); |
992 | } | 1002 | } |
993 | mutex_unlock(&state->mutex); | 1003 | mutex_unlock(&port->mutex); |
994 | return ret; | 1004 | return ret; |
995 | } | 1005 | } |
996 | 1006 | ||
@@ -999,11 +1009,15 @@ static int uart_do_autoconfig(struct uart_state *state) | |||
999 | * - mask passed in arg for lines of interest | 1009 | * - mask passed in arg for lines of interest |
1000 | * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) | 1010 | * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) |
1001 | * Caller should use TIOCGICOUNT to see which one it was | 1011 | * Caller should use TIOCGICOUNT to see which one it was |
1012 | * | ||
1013 | * FIXME: This wants extracting into a common all driver implementation | ||
1014 | * of TIOCMWAIT using tty_port. | ||
1002 | */ | 1015 | */ |
1003 | static int | 1016 | static int |
1004 | uart_wait_modem_status(struct uart_state *state, unsigned long arg) | 1017 | uart_wait_modem_status(struct uart_state *state, unsigned long arg) |
1005 | { | 1018 | { |
1006 | struct uart_port *port = state->port; | 1019 | struct uart_port *uport = state->uart_port; |
1020 | struct tty_port *port = &state->port; | ||
1007 | DECLARE_WAITQUEUE(wait, current); | 1021 | DECLARE_WAITQUEUE(wait, current); |
1008 | struct uart_icount cprev, cnow; | 1022 | struct uart_icount cprev, cnow; |
1009 | int ret; | 1023 | int ret; |
@@ -1011,20 +1025,20 @@ uart_wait_modem_status(struct uart_state *state, unsigned long arg) | |||
1011 | /* | 1025 | /* |
1012 | * note the counters on entry | 1026 | * note the counters on entry |
1013 | */ | 1027 | */ |
1014 | spin_lock_irq(&port->lock); | 1028 | spin_lock_irq(&uport->lock); |
1015 | memcpy(&cprev, &port->icount, sizeof(struct uart_icount)); | 1029 | memcpy(&cprev, &uport->icount, sizeof(struct uart_icount)); |
1016 | 1030 | ||
1017 | /* | 1031 | /* |
1018 | * Force modem status interrupts on | 1032 | * Force modem status interrupts on |
1019 | */ | 1033 | */ |
1020 | port->ops->enable_ms(port); | 1034 | uport->ops->enable_ms(uport); |
1021 | spin_unlock_irq(&port->lock); | 1035 | spin_unlock_irq(&uport->lock); |
1022 | 1036 | ||
1023 | add_wait_queue(&state->info.delta_msr_wait, &wait); | 1037 | add_wait_queue(&port->delta_msr_wait, &wait); |
1024 | for (;;) { | 1038 | for (;;) { |
1025 | spin_lock_irq(&port->lock); | 1039 | spin_lock_irq(&uport->lock); |
1026 | memcpy(&cnow, &port->icount, sizeof(struct uart_icount)); | 1040 | memcpy(&cnow, &uport->icount, sizeof(struct uart_icount)); |
1027 | spin_unlock_irq(&port->lock); | 1041 | spin_unlock_irq(&uport->lock); |
1028 | 1042 | ||
1029 | set_current_state(TASK_INTERRUPTIBLE); | 1043 | set_current_state(TASK_INTERRUPTIBLE); |
1030 | 1044 | ||
@@ -1048,7 +1062,7 @@ uart_wait_modem_status(struct uart_state *state, unsigned long arg) | |||
1048 | } | 1062 | } |
1049 | 1063 | ||
1050 | current->state = TASK_RUNNING; | 1064 | current->state = TASK_RUNNING; |
1051 | remove_wait_queue(&state->info.delta_msr_wait, &wait); | 1065 | remove_wait_queue(&port->delta_msr_wait, &wait); |
1052 | 1066 | ||
1053 | return ret; | 1067 | return ret; |
1054 | } | 1068 | } |
@@ -1059,30 +1073,30 @@ uart_wait_modem_status(struct uart_state *state, unsigned long arg) | |||
1059 | * NB: both 1->0 and 0->1 transitions are counted except for | 1073 | * NB: both 1->0 and 0->1 transitions are counted except for |
1060 | * RI where only 0->1 is counted. | 1074 | * RI where only 0->1 is counted. |
1061 | */ | 1075 | */ |
1062 | static int uart_get_count(struct uart_state *state, | 1076 | static int uart_get_icount(struct tty_struct *tty, |
1063 | struct serial_icounter_struct __user *icnt) | 1077 | struct serial_icounter_struct *icount) |
1064 | { | 1078 | { |
1065 | struct serial_icounter_struct icount; | 1079 | struct uart_state *state = tty->driver_data; |
1066 | struct uart_icount cnow; | 1080 | struct uart_icount cnow; |
1067 | struct uart_port *port = state->port; | 1081 | struct uart_port *uport = state->uart_port; |
1068 | 1082 | ||
1069 | spin_lock_irq(&port->lock); | 1083 | spin_lock_irq(&uport->lock); |
1070 | memcpy(&cnow, &port->icount, sizeof(struct uart_icount)); | 1084 | memcpy(&cnow, &uport->icount, sizeof(struct uart_icount)); |
1071 | spin_unlock_irq(&port->lock); | 1085 | spin_unlock_irq(&uport->lock); |
1086 | |||
1087 | icount->cts = cnow.cts; | ||
1088 | icount->dsr = cnow.dsr; | ||
1089 | icount->rng = cnow.rng; | ||
1090 | icount->dcd = cnow.dcd; | ||
1091 | icount->rx = cnow.rx; | ||
1092 | icount->tx = cnow.tx; | ||
1093 | icount->frame = cnow.frame; | ||
1094 | icount->overrun = cnow.overrun; | ||
1095 | icount->parity = cnow.parity; | ||
1096 | icount->brk = cnow.brk; | ||
1097 | icount->buf_overrun = cnow.buf_overrun; | ||
1072 | 1098 | ||
1073 | icount.cts = cnow.cts; | 1099 | return 0; |
1074 | icount.dsr = cnow.dsr; | ||
1075 | icount.rng = cnow.rng; | ||
1076 | icount.dcd = cnow.dcd; | ||
1077 | icount.rx = cnow.rx; | ||
1078 | icount.tx = cnow.tx; | ||
1079 | icount.frame = cnow.frame; | ||
1080 | icount.overrun = cnow.overrun; | ||
1081 | icount.parity = cnow.parity; | ||
1082 | icount.brk = cnow.brk; | ||
1083 | icount.buf_overrun = cnow.buf_overrun; | ||
1084 | |||
1085 | return copy_to_user(icnt, &icount, sizeof(icount)) ? -EFAULT : 0; | ||
1086 | } | 1100 | } |
1087 | 1101 | ||
1088 | /* | 1102 | /* |
@@ -1093,6 +1107,7 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd, | |||
1093 | unsigned long arg) | 1107 | unsigned long arg) |
1094 | { | 1108 | { |
1095 | struct uart_state *state = tty->driver_data; | 1109 | struct uart_state *state = tty->driver_data; |
1110 | struct tty_port *port = &state->port; | ||
1096 | void __user *uarg = (void __user *)arg; | 1111 | void __user *uarg = (void __user *)arg; |
1097 | int ret = -ENOIOCTLCMD; | 1112 | int ret = -ENOIOCTLCMD; |
1098 | 1113 | ||
@@ -1106,11 +1121,11 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd, | |||
1106 | break; | 1121 | break; |
1107 | 1122 | ||
1108 | case TIOCSSERIAL: | 1123 | case TIOCSSERIAL: |
1109 | ret = uart_set_info(state, uarg); | 1124 | ret = uart_set_info(tty, state, uarg); |
1110 | break; | 1125 | break; |
1111 | 1126 | ||
1112 | case TIOCSERCONFIG: | 1127 | case TIOCSERCONFIG: |
1113 | ret = uart_do_autoconfig(state); | 1128 | ret = uart_do_autoconfig(tty, state); |
1114 | break; | 1129 | break; |
1115 | 1130 | ||
1116 | case TIOCSERGWILD: /* obsolete */ | 1131 | case TIOCSERGWILD: /* obsolete */ |
@@ -1134,16 +1149,12 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd, | |||
1134 | case TIOCMIWAIT: | 1149 | case TIOCMIWAIT: |
1135 | ret = uart_wait_modem_status(state, arg); | 1150 | ret = uart_wait_modem_status(state, arg); |
1136 | break; | 1151 | break; |
1137 | |||
1138 | case TIOCGICOUNT: | ||
1139 | ret = uart_get_count(state, uarg); | ||
1140 | break; | ||
1141 | } | 1152 | } |
1142 | 1153 | ||
1143 | if (ret != -ENOIOCTLCMD) | 1154 | if (ret != -ENOIOCTLCMD) |
1144 | goto out; | 1155 | goto out; |
1145 | 1156 | ||
1146 | mutex_lock(&state->mutex); | 1157 | mutex_lock(&port->mutex); |
1147 | 1158 | ||
1148 | if (tty_hung_up_p(filp)) { | 1159 | if (tty_hung_up_p(filp)) { |
1149 | ret = -EIO; | 1160 | ret = -EIO; |
@@ -1156,18 +1167,18 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd, | |||
1156 | */ | 1167 | */ |
1157 | switch (cmd) { | 1168 | switch (cmd) { |
1158 | case TIOCSERGETLSR: /* Get line status register */ | 1169 | case TIOCSERGETLSR: /* Get line status register */ |
1159 | ret = uart_get_lsr_info(state, uarg); | 1170 | ret = uart_get_lsr_info(tty, state, uarg); |
1160 | break; | 1171 | break; |
1161 | 1172 | ||
1162 | default: { | 1173 | default: { |
1163 | struct uart_port *port = state->port; | 1174 | struct uart_port *uport = state->uart_port; |
1164 | if (port->ops->ioctl) | 1175 | if (uport->ops->ioctl) |
1165 | ret = port->ops->ioctl(port, cmd, arg); | 1176 | ret = uport->ops->ioctl(uport, cmd, arg); |
1166 | break; | 1177 | break; |
1167 | } | 1178 | } |
1168 | } | 1179 | } |
1169 | out_up: | 1180 | out_up: |
1170 | mutex_unlock(&state->mutex); | 1181 | mutex_unlock(&port->mutex); |
1171 | out: | 1182 | out: |
1172 | return ret; | 1183 | return ret; |
1173 | } | 1184 | } |
@@ -1175,10 +1186,10 @@ out: | |||
1175 | static void uart_set_ldisc(struct tty_struct *tty) | 1186 | static void uart_set_ldisc(struct tty_struct *tty) |
1176 | { | 1187 | { |
1177 | struct uart_state *state = tty->driver_data; | 1188 | struct uart_state *state = tty->driver_data; |
1178 | struct uart_port *port = state->port; | 1189 | struct uart_port *uport = state->uart_port; |
1179 | 1190 | ||
1180 | if (port->ops->set_ldisc) | 1191 | if (uport->ops->set_ldisc) |
1181 | port->ops->set_ldisc(port); | 1192 | uport->ops->set_ldisc(uport, tty->termios->c_line); |
1182 | } | 1193 | } |
1183 | 1194 | ||
1184 | static void uart_set_termios(struct tty_struct *tty, | 1195 | static void uart_set_termios(struct tty_struct *tty, |
@@ -1203,37 +1214,35 @@ static void uart_set_termios(struct tty_struct *tty, | |||
1203 | return; | 1214 | return; |
1204 | } | 1215 | } |
1205 | 1216 | ||
1206 | uart_change_speed(state, old_termios); | 1217 | uart_change_speed(tty, state, old_termios); |
1207 | 1218 | ||
1208 | /* Handle transition to B0 status */ | 1219 | /* Handle transition to B0 status */ |
1209 | if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD)) | 1220 | if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD)) |
1210 | uart_clear_mctrl(state->port, TIOCM_RTS | TIOCM_DTR); | 1221 | uart_clear_mctrl(state->uart_port, TIOCM_RTS | TIOCM_DTR); |
1211 | |||
1212 | /* Handle transition away from B0 status */ | 1222 | /* Handle transition away from B0 status */ |
1213 | if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { | 1223 | else if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { |
1214 | unsigned int mask = TIOCM_DTR; | 1224 | unsigned int mask = TIOCM_DTR; |
1215 | if (!(cflag & CRTSCTS) || | 1225 | if (!(cflag & CRTSCTS) || |
1216 | !test_bit(TTY_THROTTLED, &tty->flags)) | 1226 | !test_bit(TTY_THROTTLED, &tty->flags)) |
1217 | mask |= TIOCM_RTS; | 1227 | mask |= TIOCM_RTS; |
1218 | uart_set_mctrl(state->port, mask); | 1228 | uart_set_mctrl(state->uart_port, mask); |
1219 | } | 1229 | } |
1220 | 1230 | ||
1221 | /* Handle turning off CRTSCTS */ | 1231 | /* Handle turning off CRTSCTS */ |
1222 | if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) { | 1232 | if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) { |
1223 | spin_lock_irqsave(&state->port->lock, flags); | 1233 | spin_lock_irqsave(&state->uart_port->lock, flags); |
1224 | tty->hw_stopped = 0; | 1234 | tty->hw_stopped = 0; |
1225 | __uart_start(tty); | 1235 | __uart_start(tty); |
1226 | spin_unlock_irqrestore(&state->port->lock, flags); | 1236 | spin_unlock_irqrestore(&state->uart_port->lock, flags); |
1227 | } | 1237 | } |
1228 | |||
1229 | /* Handle turning on CRTSCTS */ | 1238 | /* Handle turning on CRTSCTS */ |
1230 | if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) { | 1239 | else if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) { |
1231 | spin_lock_irqsave(&state->port->lock, flags); | 1240 | spin_lock_irqsave(&state->uart_port->lock, flags); |
1232 | if (!(state->port->ops->get_mctrl(state->port) & TIOCM_CTS)) { | 1241 | if (!(state->uart_port->ops->get_mctrl(state->uart_port) & TIOCM_CTS)) { |
1233 | tty->hw_stopped = 1; | 1242 | tty->hw_stopped = 1; |
1234 | state->port->ops->stop_tx(state->port); | 1243 | state->uart_port->ops->stop_tx(state->uart_port); |
1235 | } | 1244 | } |
1236 | spin_unlock_irqrestore(&state->port->lock, flags); | 1245 | spin_unlock_irqrestore(&state->uart_port->lock, flags); |
1237 | } | 1246 | } |
1238 | #if 0 | 1247 | #if 0 |
1239 | /* | 1248 | /* |
@@ -1244,7 +1253,7 @@ static void uart_set_termios(struct tty_struct *tty, | |||
1244 | */ | 1253 | */ |
1245 | if (!(old_termios->c_cflag & CLOCAL) && | 1254 | if (!(old_termios->c_cflag & CLOCAL) && |
1246 | (tty->termios->c_cflag & CLOCAL)) | 1255 | (tty->termios->c_cflag & CLOCAL)) |
1247 | wake_up_interruptible(&info->port.open_wait); | 1256 | wake_up_interruptible(&state->uart_port.open_wait); |
1248 | #endif | 1257 | #endif |
1249 | } | 1258 | } |
1250 | 1259 | ||
@@ -1256,41 +1265,49 @@ static void uart_set_termios(struct tty_struct *tty, | |||
1256 | static void uart_close(struct tty_struct *tty, struct file *filp) | 1265 | static void uart_close(struct tty_struct *tty, struct file *filp) |
1257 | { | 1266 | { |
1258 | struct uart_state *state = tty->driver_data; | 1267 | struct uart_state *state = tty->driver_data; |
1259 | struct uart_port *port; | 1268 | struct tty_port *port; |
1269 | struct uart_port *uport; | ||
1270 | unsigned long flags; | ||
1260 | 1271 | ||
1261 | BUG_ON(!kernel_locked()); | 1272 | BUG_ON(!tty_locked()); |
1262 | 1273 | ||
1263 | if (!state || !state->port) | 1274 | if (!state) |
1264 | return; | 1275 | return; |
1265 | 1276 | ||
1266 | port = state->port; | 1277 | uport = state->uart_port; |
1278 | port = &state->port; | ||
1267 | 1279 | ||
1268 | pr_debug("uart_close(%d) called\n", port->line); | 1280 | pr_debug("uart_close(%d) called\n", uport->line); |
1269 | 1281 | ||
1270 | mutex_lock(&state->mutex); | 1282 | mutex_lock(&port->mutex); |
1283 | spin_lock_irqsave(&port->lock, flags); | ||
1271 | 1284 | ||
1272 | if (tty_hung_up_p(filp)) | 1285 | if (tty_hung_up_p(filp)) { |
1286 | spin_unlock_irqrestore(&port->lock, flags); | ||
1273 | goto done; | 1287 | goto done; |
1288 | } | ||
1274 | 1289 | ||
1275 | if ((tty->count == 1) && (state->count != 1)) { | 1290 | if ((tty->count == 1) && (port->count != 1)) { |
1276 | /* | 1291 | /* |
1277 | * Uh, oh. tty->count is 1, which means that the tty | 1292 | * Uh, oh. tty->count is 1, which means that the tty |
1278 | * structure will be freed. state->count should always | 1293 | * structure will be freed. port->count should always |
1279 | * be one in these conditions. If it's greater than | 1294 | * be one in these conditions. If it's greater than |
1280 | * one, we've got real problems, since it means the | 1295 | * one, we've got real problems, since it means the |
1281 | * serial port won't be shutdown. | 1296 | * serial port won't be shutdown. |
1282 | */ | 1297 | */ |
1283 | printk(KERN_ERR "uart_close: bad serial port count; tty->count is 1, " | 1298 | printk(KERN_ERR "uart_close: bad serial port count; tty->count is 1, " |
1284 | "state->count is %d\n", state->count); | 1299 | "port->count is %d\n", port->count); |
1285 | state->count = 1; | 1300 | port->count = 1; |
1286 | } | 1301 | } |
1287 | if (--state->count < 0) { | 1302 | if (--port->count < 0) { |
1288 | printk(KERN_ERR "uart_close: bad serial port count for %s: %d\n", | 1303 | printk(KERN_ERR "uart_close: bad serial port count for %s: %d\n", |
1289 | tty->name, state->count); | 1304 | tty->name, port->count); |
1290 | state->count = 0; | 1305 | port->count = 0; |
1291 | } | 1306 | } |
1292 | if (state->count) | 1307 | if (port->count) { |
1308 | spin_unlock_irqrestore(&port->lock, flags); | ||
1293 | goto done; | 1309 | goto done; |
1310 | } | ||
1294 | 1311 | ||
1295 | /* | 1312 | /* |
1296 | * Now we wait for the transmit buffer to clear; and we notify | 1313 | * Now we wait for the transmit buffer to clear; and we notify |
@@ -1298,63 +1315,74 @@ static void uart_close(struct tty_struct *tty, struct file *filp) | |||
1298 | * setting tty->closing. | 1315 | * setting tty->closing. |
1299 | */ | 1316 | */ |
1300 | tty->closing = 1; | 1317 | tty->closing = 1; |
1318 | spin_unlock_irqrestore(&port->lock, flags); | ||
1301 | 1319 | ||
1302 | if (state->closing_wait != USF_CLOSING_WAIT_NONE) | 1320 | if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) { |
1303 | tty_wait_until_sent(tty, msecs_to_jiffies(state->closing_wait)); | 1321 | /* |
1322 | * hack: open-coded tty_wait_until_sent to avoid | ||
1323 | * recursive tty_lock | ||
1324 | */ | ||
1325 | long timeout = msecs_to_jiffies(port->closing_wait); | ||
1326 | if (wait_event_interruptible_timeout(tty->write_wait, | ||
1327 | !tty_chars_in_buffer(tty), timeout) >= 0) | ||
1328 | __uart_wait_until_sent(uport, timeout); | ||
1329 | } | ||
1304 | 1330 | ||
1305 | /* | 1331 | /* |
1306 | * At this point, we stop accepting input. To do this, we | 1332 | * At this point, we stop accepting input. To do this, we |
1307 | * disable the receive line status interrupts. | 1333 | * disable the receive line status interrupts. |
1308 | */ | 1334 | */ |
1309 | if (state->info.flags & UIF_INITIALIZED) { | 1335 | if (port->flags & ASYNC_INITIALIZED) { |
1310 | unsigned long flags; | 1336 | unsigned long flags; |
1311 | spin_lock_irqsave(&port->lock, flags); | 1337 | spin_lock_irqsave(&uport->lock, flags); |
1312 | port->ops->stop_rx(port); | 1338 | uport->ops->stop_rx(uport); |
1313 | spin_unlock_irqrestore(&port->lock, flags); | 1339 | spin_unlock_irqrestore(&uport->lock, flags); |
1314 | /* | 1340 | /* |
1315 | * Before we drop DTR, make sure the UART transmitter | 1341 | * Before we drop DTR, make sure the UART transmitter |
1316 | * has completely drained; this is especially | 1342 | * has completely drained; this is especially |
1317 | * important if there is a transmit FIFO! | 1343 | * important if there is a transmit FIFO! |
1318 | */ | 1344 | */ |
1319 | uart_wait_until_sent(tty, port->timeout); | 1345 | __uart_wait_until_sent(uport, uport->timeout); |
1320 | } | 1346 | } |
1321 | 1347 | ||
1322 | uart_shutdown(state); | 1348 | uart_shutdown(tty, state); |
1323 | uart_flush_buffer(tty); | 1349 | uart_flush_buffer(tty); |
1324 | 1350 | ||
1325 | tty_ldisc_flush(tty); | 1351 | tty_ldisc_flush(tty); |
1326 | 1352 | ||
1353 | tty_port_tty_set(port, NULL); | ||
1354 | spin_lock_irqsave(&port->lock, flags); | ||
1327 | tty->closing = 0; | 1355 | tty->closing = 0; |
1328 | state->info.port.tty = NULL; | ||
1329 | 1356 | ||
1330 | if (state->info.port.blocked_open) { | 1357 | if (port->blocked_open) { |
1331 | if (state->close_delay) | 1358 | spin_unlock_irqrestore(&port->lock, flags); |
1332 | msleep_interruptible(state->close_delay); | 1359 | if (port->close_delay) |
1333 | } else if (!uart_console(port)) { | 1360 | msleep_interruptible(port->close_delay); |
1361 | spin_lock_irqsave(&port->lock, flags); | ||
1362 | } else if (!uart_console(uport)) { | ||
1363 | spin_unlock_irqrestore(&port->lock, flags); | ||
1334 | uart_change_pm(state, 3); | 1364 | uart_change_pm(state, 3); |
1365 | spin_lock_irqsave(&port->lock, flags); | ||
1335 | } | 1366 | } |
1336 | 1367 | ||
1337 | /* | 1368 | /* |
1338 | * Wake up anyone trying to open this port. | 1369 | * Wake up anyone trying to open this port. |
1339 | */ | 1370 | */ |
1340 | state->info.flags &= ~UIF_NORMAL_ACTIVE; | 1371 | clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags); |
1341 | wake_up_interruptible(&state->info.port.open_wait); | 1372 | spin_unlock_irqrestore(&port->lock, flags); |
1373 | wake_up_interruptible(&port->open_wait); | ||
1342 | 1374 | ||
1343 | done: | 1375 | done: |
1344 | mutex_unlock(&state->mutex); | 1376 | mutex_unlock(&port->mutex); |
1345 | } | 1377 | } |
1346 | 1378 | ||
1347 | static void uart_wait_until_sent(struct tty_struct *tty, int timeout) | 1379 | static void __uart_wait_until_sent(struct uart_port *port, int timeout) |
1348 | { | 1380 | { |
1349 | struct uart_state *state = tty->driver_data; | ||
1350 | struct uart_port *port = state->port; | ||
1351 | unsigned long char_time, expire; | 1381 | unsigned long char_time, expire; |
1352 | 1382 | ||
1353 | if (port->type == PORT_UNKNOWN || port->fifosize == 0) | 1383 | if (port->type == PORT_UNKNOWN || port->fifosize == 0) |
1354 | return; | 1384 | return; |
1355 | 1385 | ||
1356 | lock_kernel(); | ||
1357 | |||
1358 | /* | 1386 | /* |
1359 | * Set the check interval to be 1/5 of the estimated time to | 1387 | * Set the check interval to be 1/5 of the estimated time to |
1360 | * send a single character, and make it at least 1. The check | 1388 | * send a single character, and make it at least 1. The check |
@@ -1400,7 +1428,16 @@ static void uart_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1400 | break; | 1428 | break; |
1401 | } | 1429 | } |
1402 | set_current_state(TASK_RUNNING); /* might not be needed */ | 1430 | set_current_state(TASK_RUNNING); /* might not be needed */ |
1403 | unlock_kernel(); | 1431 | } |
1432 | |||
1433 | static void uart_wait_until_sent(struct tty_struct *tty, int timeout) | ||
1434 | { | ||
1435 | struct uart_state *state = tty->driver_data; | ||
1436 | struct uart_port *port = state->uart_port; | ||
1437 | |||
1438 | tty_lock(); | ||
1439 | __uart_wait_until_sent(port, timeout); | ||
1440 | tty_unlock(); | ||
1404 | } | 1441 | } |
1405 | 1442 | ||
1406 | /* | 1443 | /* |
@@ -1412,34 +1449,41 @@ static void uart_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1412 | static void uart_hangup(struct tty_struct *tty) | 1449 | static void uart_hangup(struct tty_struct *tty) |
1413 | { | 1450 | { |
1414 | struct uart_state *state = tty->driver_data; | 1451 | struct uart_state *state = tty->driver_data; |
1415 | struct uart_info *info = &state->info; | 1452 | struct tty_port *port = &state->port; |
1453 | unsigned long flags; | ||
1416 | 1454 | ||
1417 | BUG_ON(!kernel_locked()); | 1455 | BUG_ON(!tty_locked()); |
1418 | pr_debug("uart_hangup(%d)\n", state->port->line); | 1456 | pr_debug("uart_hangup(%d)\n", state->uart_port->line); |
1419 | 1457 | ||
1420 | mutex_lock(&state->mutex); | 1458 | mutex_lock(&port->mutex); |
1421 | if (info->flags & UIF_NORMAL_ACTIVE) { | 1459 | if (port->flags & ASYNC_NORMAL_ACTIVE) { |
1422 | uart_flush_buffer(tty); | 1460 | uart_flush_buffer(tty); |
1423 | uart_shutdown(state); | 1461 | uart_shutdown(tty, state); |
1424 | state->count = 0; | 1462 | spin_lock_irqsave(&port->lock, flags); |
1425 | info->flags &= ~UIF_NORMAL_ACTIVE; | 1463 | port->count = 0; |
1426 | info->port.tty = NULL; | 1464 | clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags); |
1427 | wake_up_interruptible(&info->port.open_wait); | 1465 | spin_unlock_irqrestore(&port->lock, flags); |
1428 | wake_up_interruptible(&info->delta_msr_wait); | 1466 | tty_port_tty_set(port, NULL); |
1467 | wake_up_interruptible(&port->open_wait); | ||
1468 | wake_up_interruptible(&port->delta_msr_wait); | ||
1429 | } | 1469 | } |
1430 | mutex_unlock(&state->mutex); | 1470 | mutex_unlock(&port->mutex); |
1431 | } | 1471 | } |
1432 | 1472 | ||
1433 | /* | 1473 | /** |
1434 | * Copy across the serial console cflag setting into the termios settings | 1474 | * uart_update_termios - update the terminal hw settings |
1435 | * for the initial open of the port. This allows continuity between the | 1475 | * @tty: tty associated with UART |
1436 | * kernel settings, and the settings init adopts when it opens the port | 1476 | * @state: UART to update |
1437 | * for the first time. | 1477 | * |
1478 | * Copy across the serial console cflag setting into the termios settings | ||
1479 | * for the initial open of the port. This allows continuity between the | ||
1480 | * kernel settings, and the settings init adopts when it opens the port | ||
1481 | * for the first time. | ||
1438 | */ | 1482 | */ |
1439 | static void uart_update_termios(struct uart_state *state) | 1483 | static void uart_update_termios(struct tty_struct *tty, |
1484 | struct uart_state *state) | ||
1440 | { | 1485 | { |
1441 | struct tty_struct *tty = state->info.port.tty; | 1486 | struct uart_port *port = state->uart_port; |
1442 | struct uart_port *port = state->port; | ||
1443 | 1487 | ||
1444 | if (uart_console(port) && port->cons->cflag) { | 1488 | if (uart_console(port) && port->cons->cflag) { |
1445 | tty->termios->c_cflag = port->cons->cflag; | 1489 | tty->termios->c_cflag = port->cons->cflag; |
@@ -1455,7 +1499,7 @@ static void uart_update_termios(struct uart_state *state) | |||
1455 | /* | 1499 | /* |
1456 | * Make termios settings take effect. | 1500 | * Make termios settings take effect. |
1457 | */ | 1501 | */ |
1458 | uart_change_speed(state, NULL); | 1502 | uart_change_speed(tty, state, NULL); |
1459 | 1503 | ||
1460 | /* | 1504 | /* |
1461 | * And finally enable the RTS and DTR signals. | 1505 | * And finally enable the RTS and DTR signals. |
@@ -1465,113 +1509,62 @@ static void uart_update_termios(struct uart_state *state) | |||
1465 | } | 1509 | } |
1466 | } | 1510 | } |
1467 | 1511 | ||
1468 | /* | 1512 | static int uart_carrier_raised(struct tty_port *port) |
1469 | * Block the open until the port is ready. We must be called with | ||
1470 | * the per-port semaphore held. | ||
1471 | */ | ||
1472 | static int | ||
1473 | uart_block_til_ready(struct file *filp, struct uart_state *state) | ||
1474 | { | 1513 | { |
1475 | DECLARE_WAITQUEUE(wait, current); | 1514 | struct uart_state *state = container_of(port, struct uart_state, port); |
1476 | struct uart_info *info = &state->info; | 1515 | struct uart_port *uport = state->uart_port; |
1477 | struct uart_port *port = state->port; | 1516 | int mctrl; |
1478 | unsigned int mctrl; | 1517 | spin_lock_irq(&uport->lock); |
1479 | 1518 | uport->ops->enable_ms(uport); | |
1480 | info->port.blocked_open++; | 1519 | mctrl = uport->ops->get_mctrl(uport); |
1481 | state->count--; | 1520 | spin_unlock_irq(&uport->lock); |
1482 | 1521 | if (mctrl & TIOCM_CAR) | |
1483 | add_wait_queue(&info->port.open_wait, &wait); | 1522 | return 1; |
1484 | while (1) { | 1523 | return 0; |
1485 | set_current_state(TASK_INTERRUPTIBLE); | 1524 | } |
1486 | |||
1487 | /* | ||
1488 | * If we have been hung up, tell userspace/restart open. | ||
1489 | */ | ||
1490 | if (tty_hung_up_p(filp) || info->port.tty == NULL) | ||
1491 | break; | ||
1492 | |||
1493 | /* | ||
1494 | * If the port has been closed, tell userspace/restart open. | ||
1495 | */ | ||
1496 | if (!(info->flags & UIF_INITIALIZED)) | ||
1497 | break; | ||
1498 | 1525 | ||
1499 | /* | 1526 | static void uart_dtr_rts(struct tty_port *port, int onoff) |
1500 | * If non-blocking mode is set, or CLOCAL mode is set, | 1527 | { |
1501 | * we don't want to wait for the modem status lines to | 1528 | struct uart_state *state = container_of(port, struct uart_state, port); |
1502 | * indicate that the port is ready. | 1529 | struct uart_port *uport = state->uart_port; |
1503 | * | ||
1504 | * Also, if the port is not enabled/configured, we want | ||
1505 | * to allow the open to succeed here. Note that we will | ||
1506 | * have set TTY_IO_ERROR for a non-existant port. | ||
1507 | */ | ||
1508 | if ((filp->f_flags & O_NONBLOCK) || | ||
1509 | (info->port.tty->termios->c_cflag & CLOCAL) || | ||
1510 | (info->port.tty->flags & (1 << TTY_IO_ERROR))) | ||
1511 | break; | ||
1512 | 1530 | ||
1513 | /* | 1531 | if (onoff) { |
1514 | * Set DTR to allow modem to know we're waiting. Do | 1532 | uart_set_mctrl(uport, TIOCM_DTR | TIOCM_RTS); |
1515 | * not set RTS here - we want to make sure we catch | ||
1516 | * the data from the modem. | ||
1517 | */ | ||
1518 | if (info->port.tty->termios->c_cflag & CBAUD) | ||
1519 | uart_set_mctrl(port, TIOCM_DTR); | ||
1520 | 1533 | ||
1521 | /* | 1534 | /* |
1522 | * and wait for the carrier to indicate that the | 1535 | * If this is the first open to succeed, |
1523 | * modem is ready for us. | 1536 | * adjust things to suit. |
1524 | */ | 1537 | */ |
1525 | spin_lock_irq(&port->lock); | 1538 | if (!test_and_set_bit(ASYNCB_NORMAL_ACTIVE, &port->flags)) |
1526 | port->ops->enable_ms(port); | 1539 | uart_update_termios(port->tty, state); |
1527 | mctrl = port->ops->get_mctrl(port); | ||
1528 | spin_unlock_irq(&port->lock); | ||
1529 | if (mctrl & TIOCM_CAR) | ||
1530 | break; | ||
1531 | |||
1532 | mutex_unlock(&state->mutex); | ||
1533 | schedule(); | ||
1534 | mutex_lock(&state->mutex); | ||
1535 | |||
1536 | if (signal_pending(current)) | ||
1537 | break; | ||
1538 | } | 1540 | } |
1539 | set_current_state(TASK_RUNNING); | 1541 | else |
1540 | remove_wait_queue(&info->port.open_wait, &wait); | 1542 | uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS); |
1541 | |||
1542 | state->count++; | ||
1543 | info->port.blocked_open--; | ||
1544 | |||
1545 | if (signal_pending(current)) | ||
1546 | return -ERESTARTSYS; | ||
1547 | |||
1548 | if (!info->port.tty || tty_hung_up_p(filp)) | ||
1549 | return -EAGAIN; | ||
1550 | |||
1551 | return 0; | ||
1552 | } | 1543 | } |
1553 | 1544 | ||
1554 | static struct uart_state *uart_get(struct uart_driver *drv, int line) | 1545 | static struct uart_state *uart_get(struct uart_driver *drv, int line) |
1555 | { | 1546 | { |
1556 | struct uart_state *state; | 1547 | struct uart_state *state; |
1548 | struct tty_port *port; | ||
1557 | int ret = 0; | 1549 | int ret = 0; |
1558 | 1550 | ||
1559 | state = drv->state + line; | 1551 | state = drv->state + line; |
1560 | if (mutex_lock_interruptible(&state->mutex)) { | 1552 | port = &state->port; |
1553 | if (mutex_lock_interruptible(&port->mutex)) { | ||
1561 | ret = -ERESTARTSYS; | 1554 | ret = -ERESTARTSYS; |
1562 | goto err; | 1555 | goto err; |
1563 | } | 1556 | } |
1564 | 1557 | ||
1565 | state->count++; | 1558 | port->count++; |
1566 | if (!state->port || state->port->flags & UPF_DEAD) { | 1559 | if (!state->uart_port || state->uart_port->flags & UPF_DEAD) { |
1567 | ret = -ENXIO; | 1560 | ret = -ENXIO; |
1568 | goto err_unlock; | 1561 | goto err_unlock; |
1569 | } | 1562 | } |
1570 | return state; | 1563 | return state; |
1571 | 1564 | ||
1572 | err_unlock: | 1565 | err_unlock: |
1573 | state->count--; | 1566 | port->count--; |
1574 | mutex_unlock(&state->mutex); | 1567 | mutex_unlock(&port->mutex); |
1575 | err: | 1568 | err: |
1576 | return ERR_PTR(ret); | 1569 | return ERR_PTR(ret); |
1577 | } | 1570 | } |
@@ -1590,9 +1583,10 @@ static int uart_open(struct tty_struct *tty, struct file *filp) | |||
1590 | { | 1583 | { |
1591 | struct uart_driver *drv = (struct uart_driver *)tty->driver->driver_state; | 1584 | struct uart_driver *drv = (struct uart_driver *)tty->driver->driver_state; |
1592 | struct uart_state *state; | 1585 | struct uart_state *state; |
1586 | struct tty_port *port; | ||
1593 | int retval, line = tty->index; | 1587 | int retval, line = tty->index; |
1594 | 1588 | ||
1595 | BUG_ON(!kernel_locked()); | 1589 | BUG_ON(!tty_locked()); |
1596 | pr_debug("uart_open(%d) called\n", line); | 1590 | pr_debug("uart_open(%d) called\n", line); |
1597 | 1591 | ||
1598 | /* | 1592 | /* |
@@ -1606,16 +1600,18 @@ static int uart_open(struct tty_struct *tty, struct file *filp) | |||
1606 | 1600 | ||
1607 | /* | 1601 | /* |
1608 | * We take the semaphore inside uart_get to guarantee that we won't | 1602 | * We take the semaphore inside uart_get to guarantee that we won't |
1609 | * be re-entered while allocating the info structure, or while we | 1603 | * be re-entered while allocating the state structure, or while we |
1610 | * request any IRQs that the driver may need. This also has the nice | 1604 | * request any IRQs that the driver may need. This also has the nice |
1611 | * side-effect that it delays the action of uart_hangup, so we can | 1605 | * side-effect that it delays the action of uart_hangup, so we can |
1612 | * guarantee that info->port.tty will always contain something reasonable. | 1606 | * guarantee that state->port.tty will always contain something |
1607 | * reasonable. | ||
1613 | */ | 1608 | */ |
1614 | state = uart_get(drv, line); | 1609 | state = uart_get(drv, line); |
1615 | if (IS_ERR(state)) { | 1610 | if (IS_ERR(state)) { |
1616 | retval = PTR_ERR(state); | 1611 | retval = PTR_ERR(state); |
1617 | goto fail; | 1612 | goto fail; |
1618 | } | 1613 | } |
1614 | port = &state->port; | ||
1619 | 1615 | ||
1620 | /* | 1616 | /* |
1621 | * Once we set tty->driver_data here, we are guaranteed that | 1617 | * Once we set tty->driver_data here, we are guaranteed that |
@@ -1623,49 +1619,40 @@ static int uart_open(struct tty_struct *tty, struct file *filp) | |||
1623 | * Any failures from here onwards should not touch the count. | 1619 | * Any failures from here onwards should not touch the count. |
1624 | */ | 1620 | */ |
1625 | tty->driver_data = state; | 1621 | tty->driver_data = state; |
1626 | state->port->info = &state->info; | 1622 | state->uart_port->state = state; |
1627 | tty->low_latency = (state->port->flags & UPF_LOW_LATENCY) ? 1 : 0; | 1623 | tty->low_latency = (state->uart_port->flags & UPF_LOW_LATENCY) ? 1 : 0; |
1628 | tty->alt_speed = 0; | 1624 | tty->alt_speed = 0; |
1629 | state->info.port.tty = tty; | 1625 | tty_port_tty_set(port, tty); |
1630 | 1626 | ||
1631 | /* | 1627 | /* |
1632 | * If the port is in the middle of closing, bail out now. | 1628 | * If the port is in the middle of closing, bail out now. |
1633 | */ | 1629 | */ |
1634 | if (tty_hung_up_p(filp)) { | 1630 | if (tty_hung_up_p(filp)) { |
1635 | retval = -EAGAIN; | 1631 | retval = -EAGAIN; |
1636 | state->count--; | 1632 | port->count--; |
1637 | mutex_unlock(&state->mutex); | 1633 | mutex_unlock(&port->mutex); |
1638 | goto fail; | 1634 | goto fail; |
1639 | } | 1635 | } |
1640 | 1636 | ||
1641 | /* | 1637 | /* |
1642 | * Make sure the device is in D0 state. | 1638 | * Make sure the device is in D0 state. |
1643 | */ | 1639 | */ |
1644 | if (state->count == 1) | 1640 | if (port->count == 1) |
1645 | uart_change_pm(state, 0); | 1641 | uart_change_pm(state, 0); |
1646 | 1642 | ||
1647 | /* | 1643 | /* |
1648 | * Start up the serial port. | 1644 | * Start up the serial port. |
1649 | */ | 1645 | */ |
1650 | retval = uart_startup(state, 0); | 1646 | retval = uart_startup(tty, state, 0); |
1651 | 1647 | ||
1652 | /* | 1648 | /* |
1653 | * If we succeeded, wait until the port is ready. | 1649 | * If we succeeded, wait until the port is ready. |
1654 | */ | 1650 | */ |
1651 | mutex_unlock(&port->mutex); | ||
1655 | if (retval == 0) | 1652 | if (retval == 0) |
1656 | retval = uart_block_til_ready(filp, state); | 1653 | retval = tty_port_block_til_ready(port, tty, filp); |
1657 | mutex_unlock(&state->mutex); | ||
1658 | |||
1659 | /* | ||
1660 | * If this is the first open to succeed, adjust things to suit. | ||
1661 | */ | ||
1662 | if (retval == 0 && !(state->info.flags & UIF_NORMAL_ACTIVE)) { | ||
1663 | state->info.flags |= UIF_NORMAL_ACTIVE; | ||
1664 | |||
1665 | uart_update_termios(state); | ||
1666 | } | ||
1667 | 1654 | ||
1668 | fail: | 1655 | fail: |
1669 | return retval; | 1656 | return retval; |
1670 | } | 1657 | } |
1671 | 1658 | ||
@@ -1687,57 +1674,58 @@ static const char *uart_type(struct uart_port *port) | |||
1687 | static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i) | 1674 | static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i) |
1688 | { | 1675 | { |
1689 | struct uart_state *state = drv->state + i; | 1676 | struct uart_state *state = drv->state + i; |
1677 | struct tty_port *port = &state->port; | ||
1690 | int pm_state; | 1678 | int pm_state; |
1691 | struct uart_port *port = state->port; | 1679 | struct uart_port *uport = state->uart_port; |
1692 | char stat_buf[32]; | 1680 | char stat_buf[32]; |
1693 | unsigned int status; | 1681 | unsigned int status; |
1694 | int mmio; | 1682 | int mmio; |
1695 | 1683 | ||
1696 | if (!port) | 1684 | if (!uport) |
1697 | return; | 1685 | return; |
1698 | 1686 | ||
1699 | mmio = port->iotype >= UPIO_MEM; | 1687 | mmio = uport->iotype >= UPIO_MEM; |
1700 | seq_printf(m, "%d: uart:%s %s%08llX irq:%d", | 1688 | seq_printf(m, "%d: uart:%s %s%08llX irq:%d", |
1701 | port->line, uart_type(port), | 1689 | uport->line, uart_type(uport), |
1702 | mmio ? "mmio:0x" : "port:", | 1690 | mmio ? "mmio:0x" : "port:", |
1703 | mmio ? (unsigned long long)port->mapbase | 1691 | mmio ? (unsigned long long)uport->mapbase |
1704 | : (unsigned long long) port->iobase, | 1692 | : (unsigned long long)uport->iobase, |
1705 | port->irq); | 1693 | uport->irq); |
1706 | 1694 | ||
1707 | if (port->type == PORT_UNKNOWN) { | 1695 | if (uport->type == PORT_UNKNOWN) { |
1708 | seq_putc(m, '\n'); | 1696 | seq_putc(m, '\n'); |
1709 | return; | 1697 | return; |
1710 | } | 1698 | } |
1711 | 1699 | ||
1712 | if (capable(CAP_SYS_ADMIN)) { | 1700 | if (capable(CAP_SYS_ADMIN)) { |
1713 | mutex_lock(&state->mutex); | 1701 | mutex_lock(&port->mutex); |
1714 | pm_state = state->pm_state; | 1702 | pm_state = state->pm_state; |
1715 | if (pm_state) | 1703 | if (pm_state) |
1716 | uart_change_pm(state, 0); | 1704 | uart_change_pm(state, 0); |
1717 | spin_lock_irq(&port->lock); | 1705 | spin_lock_irq(&uport->lock); |
1718 | status = port->ops->get_mctrl(port); | 1706 | status = uport->ops->get_mctrl(uport); |
1719 | spin_unlock_irq(&port->lock); | 1707 | spin_unlock_irq(&uport->lock); |
1720 | if (pm_state) | 1708 | if (pm_state) |
1721 | uart_change_pm(state, pm_state); | 1709 | uart_change_pm(state, pm_state); |
1722 | mutex_unlock(&state->mutex); | 1710 | mutex_unlock(&port->mutex); |
1723 | 1711 | ||
1724 | seq_printf(m, " tx:%d rx:%d", | 1712 | seq_printf(m, " tx:%d rx:%d", |
1725 | port->icount.tx, port->icount.rx); | 1713 | uport->icount.tx, uport->icount.rx); |
1726 | if (port->icount.frame) | 1714 | if (uport->icount.frame) |
1727 | seq_printf(m, " fe:%d", | 1715 | seq_printf(m, " fe:%d", |
1728 | port->icount.frame); | 1716 | uport->icount.frame); |
1729 | if (port->icount.parity) | 1717 | if (uport->icount.parity) |
1730 | seq_printf(m, " pe:%d", | 1718 | seq_printf(m, " pe:%d", |
1731 | port->icount.parity); | 1719 | uport->icount.parity); |
1732 | if (port->icount.brk) | 1720 | if (uport->icount.brk) |
1733 | seq_printf(m, " brk:%d", | 1721 | seq_printf(m, " brk:%d", |
1734 | port->icount.brk); | 1722 | uport->icount.brk); |
1735 | if (port->icount.overrun) | 1723 | if (uport->icount.overrun) |
1736 | seq_printf(m, " oe:%d", | 1724 | seq_printf(m, " oe:%d", |
1737 | port->icount.overrun); | 1725 | uport->icount.overrun); |
1738 | 1726 | ||
1739 | #define INFOBIT(bit, str) \ | 1727 | #define INFOBIT(bit, str) \ |
1740 | if (port->mctrl & (bit)) \ | 1728 | if (uport->mctrl & (bit)) \ |
1741 | strncat(stat_buf, (str), sizeof(stat_buf) - \ | 1729 | strncat(stat_buf, (str), sizeof(stat_buf) - \ |
1742 | strlen(stat_buf) - 2) | 1730 | strlen(stat_buf) - 2) |
1743 | #define STATBIT(bit, str) \ | 1731 | #define STATBIT(bit, str) \ |
@@ -1958,7 +1946,7 @@ EXPORT_SYMBOL_GPL(uart_set_options); | |||
1958 | 1946 | ||
1959 | static void uart_change_pm(struct uart_state *state, int pm_state) | 1947 | static void uart_change_pm(struct uart_state *state, int pm_state) |
1960 | { | 1948 | { |
1961 | struct uart_port *port = state->port; | 1949 | struct uart_port *port = state->uart_port; |
1962 | 1950 | ||
1963 | if (state->pm_state != pm_state) { | 1951 | if (state->pm_state != pm_state) { |
1964 | if (port->ops->pm) | 1952 | if (port->ops->pm) |
@@ -1982,145 +1970,152 @@ static int serial_match_port(struct device *dev, void *data) | |||
1982 | return dev->devt == devt; /* Actually, only one tty per port */ | 1970 | return dev->devt == devt; /* Actually, only one tty per port */ |
1983 | } | 1971 | } |
1984 | 1972 | ||
1985 | int uart_suspend_port(struct uart_driver *drv, struct uart_port *port) | 1973 | int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) |
1986 | { | 1974 | { |
1987 | struct uart_state *state = drv->state + port->line; | 1975 | struct uart_state *state = drv->state + uport->line; |
1976 | struct tty_port *port = &state->port; | ||
1988 | struct device *tty_dev; | 1977 | struct device *tty_dev; |
1989 | struct uart_match match = {port, drv}; | 1978 | struct uart_match match = {uport, drv}; |
1979 | struct tty_struct *tty; | ||
1990 | 1980 | ||
1991 | mutex_lock(&state->mutex); | 1981 | mutex_lock(&port->mutex); |
1992 | 1982 | ||
1993 | if (!console_suspend_enabled && uart_console(port)) { | 1983 | /* Must be inside the mutex lock until we convert to tty_port */ |
1994 | /* we're going to avoid suspending serial console */ | 1984 | tty = port->tty; |
1995 | mutex_unlock(&state->mutex); | ||
1996 | return 0; | ||
1997 | } | ||
1998 | 1985 | ||
1999 | tty_dev = device_find_child(port->dev, &match, serial_match_port); | 1986 | tty_dev = device_find_child(uport->dev, &match, serial_match_port); |
2000 | if (device_may_wakeup(tty_dev)) { | 1987 | if (device_may_wakeup(tty_dev)) { |
2001 | enable_irq_wake(port->irq); | 1988 | if (!enable_irq_wake(uport->irq)) |
1989 | uport->irq_wake = 1; | ||
2002 | put_device(tty_dev); | 1990 | put_device(tty_dev); |
2003 | mutex_unlock(&state->mutex); | 1991 | mutex_unlock(&port->mutex); |
2004 | return 0; | 1992 | return 0; |
2005 | } | 1993 | } |
2006 | port->suspended = 1; | 1994 | if (console_suspend_enabled || !uart_console(uport)) |
1995 | uport->suspended = 1; | ||
2007 | 1996 | ||
2008 | if (state->info.flags & UIF_INITIALIZED) { | 1997 | if (port->flags & ASYNC_INITIALIZED) { |
2009 | const struct uart_ops *ops = port->ops; | 1998 | const struct uart_ops *ops = uport->ops; |
2010 | int tries; | 1999 | int tries; |
2011 | 2000 | ||
2012 | state->info.flags = (state->info.flags & ~UIF_INITIALIZED) | 2001 | if (console_suspend_enabled || !uart_console(uport)) { |
2013 | | UIF_SUSPENDED; | 2002 | set_bit(ASYNCB_SUSPENDED, &port->flags); |
2003 | clear_bit(ASYNCB_INITIALIZED, &port->flags); | ||
2014 | 2004 | ||
2015 | spin_lock_irq(&port->lock); | 2005 | spin_lock_irq(&uport->lock); |
2016 | ops->stop_tx(port); | 2006 | ops->stop_tx(uport); |
2017 | ops->set_mctrl(port, 0); | 2007 | ops->set_mctrl(uport, 0); |
2018 | ops->stop_rx(port); | 2008 | ops->stop_rx(uport); |
2019 | spin_unlock_irq(&port->lock); | 2009 | spin_unlock_irq(&uport->lock); |
2010 | } | ||
2020 | 2011 | ||
2021 | /* | 2012 | /* |
2022 | * Wait for the transmitter to empty. | 2013 | * Wait for the transmitter to empty. |
2023 | */ | 2014 | */ |
2024 | for (tries = 3; !ops->tx_empty(port) && tries; tries--) | 2015 | for (tries = 3; !ops->tx_empty(uport) && tries; tries--) |
2025 | msleep(10); | 2016 | msleep(10); |
2026 | if (!tries) | 2017 | if (!tries) |
2027 | printk(KERN_ERR "%s%s%s%d: Unable to drain " | 2018 | printk(KERN_ERR "%s%s%s%d: Unable to drain " |
2028 | "transmitter\n", | 2019 | "transmitter\n", |
2029 | port->dev ? dev_name(port->dev) : "", | 2020 | uport->dev ? dev_name(uport->dev) : "", |
2030 | port->dev ? ": " : "", | 2021 | uport->dev ? ": " : "", |
2031 | drv->dev_name, | 2022 | drv->dev_name, |
2032 | drv->tty_driver->name_base + port->line); | 2023 | drv->tty_driver->name_base + uport->line); |
2033 | 2024 | ||
2034 | ops->shutdown(port); | 2025 | if (console_suspend_enabled || !uart_console(uport)) |
2026 | ops->shutdown(uport); | ||
2035 | } | 2027 | } |
2036 | 2028 | ||
2037 | /* | 2029 | /* |
2038 | * Disable the console device before suspending. | 2030 | * Disable the console device before suspending. |
2039 | */ | 2031 | */ |
2040 | if (uart_console(port)) | 2032 | if (console_suspend_enabled && uart_console(uport)) |
2041 | console_stop(port->cons); | 2033 | console_stop(uport->cons); |
2042 | 2034 | ||
2043 | uart_change_pm(state, 3); | 2035 | if (console_suspend_enabled || !uart_console(uport)) |
2036 | uart_change_pm(state, 3); | ||
2044 | 2037 | ||
2045 | mutex_unlock(&state->mutex); | 2038 | mutex_unlock(&port->mutex); |
2046 | 2039 | ||
2047 | return 0; | 2040 | return 0; |
2048 | } | 2041 | } |
2049 | 2042 | ||
2050 | int uart_resume_port(struct uart_driver *drv, struct uart_port *port) | 2043 | int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) |
2051 | { | 2044 | { |
2052 | struct uart_state *state = drv->state + port->line; | 2045 | struct uart_state *state = drv->state + uport->line; |
2046 | struct tty_port *port = &state->port; | ||
2053 | struct device *tty_dev; | 2047 | struct device *tty_dev; |
2054 | struct uart_match match = {port, drv}; | 2048 | struct uart_match match = {uport, drv}; |
2055 | 2049 | struct ktermios termios; | |
2056 | mutex_lock(&state->mutex); | ||
2057 | 2050 | ||
2058 | if (!console_suspend_enabled && uart_console(port)) { | 2051 | mutex_lock(&port->mutex); |
2059 | /* no need to resume serial console, it wasn't suspended */ | ||
2060 | mutex_unlock(&state->mutex); | ||
2061 | return 0; | ||
2062 | } | ||
2063 | 2052 | ||
2064 | tty_dev = device_find_child(port->dev, &match, serial_match_port); | 2053 | tty_dev = device_find_child(uport->dev, &match, serial_match_port); |
2065 | if (!port->suspended && device_may_wakeup(tty_dev)) { | 2054 | if (!uport->suspended && device_may_wakeup(tty_dev)) { |
2066 | disable_irq_wake(port->irq); | 2055 | if (uport->irq_wake) { |
2067 | mutex_unlock(&state->mutex); | 2056 | disable_irq_wake(uport->irq); |
2057 | uport->irq_wake = 0; | ||
2058 | } | ||
2059 | mutex_unlock(&port->mutex); | ||
2068 | return 0; | 2060 | return 0; |
2069 | } | 2061 | } |
2070 | port->suspended = 0; | 2062 | uport->suspended = 0; |
2071 | 2063 | ||
2072 | /* | 2064 | /* |
2073 | * Re-enable the console device after suspending. | 2065 | * Re-enable the console device after suspending. |
2074 | */ | 2066 | */ |
2075 | if (uart_console(port)) { | 2067 | if (console_suspend_enabled && uart_console(uport)) { |
2076 | struct ktermios termios; | ||
2077 | |||
2078 | /* | 2068 | /* |
2079 | * First try to use the console cflag setting. | 2069 | * First try to use the console cflag setting. |
2080 | */ | 2070 | */ |
2081 | memset(&termios, 0, sizeof(struct ktermios)); | 2071 | memset(&termios, 0, sizeof(struct ktermios)); |
2082 | termios.c_cflag = port->cons->cflag; | 2072 | termios.c_cflag = uport->cons->cflag; |
2083 | 2073 | ||
2084 | /* | 2074 | /* |
2085 | * If that's unset, use the tty termios setting. | 2075 | * If that's unset, use the tty termios setting. |
2086 | */ | 2076 | */ |
2087 | if (state->info.port.tty && termios.c_cflag == 0) | 2077 | if (port->tty && port->tty->termios && termios.c_cflag == 0) |
2088 | termios = *state->info.port.tty->termios; | 2078 | termios = *(port->tty->termios); |
2089 | 2079 | ||
2090 | uart_change_pm(state, 0); | 2080 | uart_change_pm(state, 0); |
2091 | port->ops->set_termios(port, &termios, NULL); | 2081 | uport->ops->set_termios(uport, &termios, NULL); |
2092 | console_start(port->cons); | 2082 | console_start(uport->cons); |
2093 | } | 2083 | } |
2094 | 2084 | ||
2095 | if (state->info.flags & UIF_SUSPENDED) { | 2085 | if (port->flags & ASYNC_SUSPENDED) { |
2096 | const struct uart_ops *ops = port->ops; | 2086 | const struct uart_ops *ops = uport->ops; |
2097 | int ret; | 2087 | int ret; |
2098 | 2088 | ||
2099 | uart_change_pm(state, 0); | 2089 | uart_change_pm(state, 0); |
2100 | spin_lock_irq(&port->lock); | 2090 | spin_lock_irq(&uport->lock); |
2101 | ops->set_mctrl(port, 0); | 2091 | ops->set_mctrl(uport, 0); |
2102 | spin_unlock_irq(&port->lock); | 2092 | spin_unlock_irq(&uport->lock); |
2103 | ret = ops->startup(port); | 2093 | if (console_suspend_enabled || !uart_console(uport)) { |
2104 | if (ret == 0) { | 2094 | /* Protected by port mutex for now */ |
2105 | uart_change_speed(state, NULL); | 2095 | struct tty_struct *tty = port->tty; |
2106 | spin_lock_irq(&port->lock); | 2096 | ret = ops->startup(uport); |
2107 | ops->set_mctrl(port, port->mctrl); | 2097 | if (ret == 0) { |
2108 | ops->start_tx(port); | 2098 | if (tty) |
2109 | spin_unlock_irq(&port->lock); | 2099 | uart_change_speed(tty, state, NULL); |
2110 | state->info.flags |= UIF_INITIALIZED; | 2100 | spin_lock_irq(&uport->lock); |
2111 | } else { | 2101 | ops->set_mctrl(uport, uport->mctrl); |
2112 | /* | 2102 | ops->start_tx(uport); |
2113 | * Failed to resume - maybe hardware went away? | 2103 | spin_unlock_irq(&uport->lock); |
2114 | * Clear the "initialized" flag so we won't try | 2104 | set_bit(ASYNCB_INITIALIZED, &port->flags); |
2115 | * to call the low level drivers shutdown method. | 2105 | } else { |
2116 | */ | 2106 | /* |
2117 | uart_shutdown(state); | 2107 | * Failed to resume - maybe hardware went away? |
2108 | * Clear the "initialized" flag so we won't try | ||
2109 | * to call the low level drivers shutdown method. | ||
2110 | */ | ||
2111 | uart_shutdown(tty, state); | ||
2112 | } | ||
2118 | } | 2113 | } |
2119 | 2114 | ||
2120 | state->info.flags &= ~UIF_SUSPENDED; | 2115 | clear_bit(ASYNCB_SUSPENDED, &port->flags); |
2121 | } | 2116 | } |
2122 | 2117 | ||
2123 | mutex_unlock(&state->mutex); | 2118 | mutex_unlock(&port->mutex); |
2124 | 2119 | ||
2125 | return 0; | 2120 | return 0; |
2126 | } | 2121 | } |
@@ -2143,6 +2138,7 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port) | |||
2143 | case UPIO_AU: | 2138 | case UPIO_AU: |
2144 | case UPIO_TSI: | 2139 | case UPIO_TSI: |
2145 | case UPIO_DWAPB: | 2140 | case UPIO_DWAPB: |
2141 | case UPIO_DWAPB32: | ||
2146 | snprintf(address, sizeof(address), | 2142 | snprintf(address, sizeof(address), |
2147 | "MMIO 0x%llx", (unsigned long long)port->mapbase); | 2143 | "MMIO 0x%llx", (unsigned long long)port->mapbase); |
2148 | break; | 2144 | break; |
@@ -2232,10 +2228,10 @@ static int uart_poll_init(struct tty_driver *driver, int line, char *options) | |||
2232 | int parity = 'n'; | 2228 | int parity = 'n'; |
2233 | int flow = 'n'; | 2229 | int flow = 'n'; |
2234 | 2230 | ||
2235 | if (!state || !state->port) | 2231 | if (!state || !state->uart_port) |
2236 | return -1; | 2232 | return -1; |
2237 | 2233 | ||
2238 | port = state->port; | 2234 | port = state->uart_port; |
2239 | if (!(port->ops->poll_get_char && port->ops->poll_put_char)) | 2235 | if (!(port->ops->poll_get_char && port->ops->poll_put_char)) |
2240 | return -1; | 2236 | return -1; |
2241 | 2237 | ||
@@ -2253,10 +2249,10 @@ static int uart_poll_get_char(struct tty_driver *driver, int line) | |||
2253 | struct uart_state *state = drv->state + line; | 2249 | struct uart_state *state = drv->state + line; |
2254 | struct uart_port *port; | 2250 | struct uart_port *port; |
2255 | 2251 | ||
2256 | if (!state || !state->port) | 2252 | if (!state || !state->uart_port) |
2257 | return -1; | 2253 | return -1; |
2258 | 2254 | ||
2259 | port = state->port; | 2255 | port = state->uart_port; |
2260 | return port->ops->poll_get_char(port); | 2256 | return port->ops->poll_get_char(port); |
2261 | } | 2257 | } |
2262 | 2258 | ||
@@ -2266,10 +2262,10 @@ static void uart_poll_put_char(struct tty_driver *driver, int line, char ch) | |||
2266 | struct uart_state *state = drv->state + line; | 2262 | struct uart_state *state = drv->state + line; |
2267 | struct uart_port *port; | 2263 | struct uart_port *port; |
2268 | 2264 | ||
2269 | if (!state || !state->port) | 2265 | if (!state || !state->uart_port) |
2270 | return; | 2266 | return; |
2271 | 2267 | ||
2272 | port = state->port; | 2268 | port = state->uart_port; |
2273 | port->ops->poll_put_char(port, ch); | 2269 | port->ops->poll_put_char(port, ch); |
2274 | } | 2270 | } |
2275 | #endif | 2271 | #endif |
@@ -2299,6 +2295,7 @@ static const struct tty_operations uart_ops = { | |||
2299 | #endif | 2295 | #endif |
2300 | .tiocmget = uart_tiocmget, | 2296 | .tiocmget = uart_tiocmget, |
2301 | .tiocmset = uart_tiocmset, | 2297 | .tiocmset = uart_tiocmset, |
2298 | .get_icount = uart_get_icount, | ||
2302 | #ifdef CONFIG_CONSOLE_POLL | 2299 | #ifdef CONFIG_CONSOLE_POLL |
2303 | .poll_init = uart_poll_init, | 2300 | .poll_init = uart_poll_init, |
2304 | .poll_get_char = uart_poll_get_char, | 2301 | .poll_get_char = uart_poll_get_char, |
@@ -2306,6 +2303,11 @@ static const struct tty_operations uart_ops = { | |||
2306 | #endif | 2303 | #endif |
2307 | }; | 2304 | }; |
2308 | 2305 | ||
2306 | static const struct tty_port_operations uart_port_ops = { | ||
2307 | .carrier_raised = uart_carrier_raised, | ||
2308 | .dtr_rts = uart_dtr_rts, | ||
2309 | }; | ||
2310 | |||
2309 | /** | 2311 | /** |
2310 | * uart_register_driver - register a driver with the uart core layer | 2312 | * uart_register_driver - register a driver with the uart core layer |
2311 | * @drv: low level driver structure | 2313 | * @drv: low level driver structure |
@@ -2321,7 +2323,7 @@ static const struct tty_operations uart_ops = { | |||
2321 | */ | 2323 | */ |
2322 | int uart_register_driver(struct uart_driver *drv) | 2324 | int uart_register_driver(struct uart_driver *drv) |
2323 | { | 2325 | { |
2324 | struct tty_driver *normal = NULL; | 2326 | struct tty_driver *normal; |
2325 | int i, retval; | 2327 | int i, retval; |
2326 | 2328 | ||
2327 | BUG_ON(drv->state); | 2329 | BUG_ON(drv->state); |
@@ -2331,13 +2333,12 @@ int uart_register_driver(struct uart_driver *drv) | |||
2331 | * we have a large number of ports to handle. | 2333 | * we have a large number of ports to handle. |
2332 | */ | 2334 | */ |
2333 | drv->state = kzalloc(sizeof(struct uart_state) * drv->nr, GFP_KERNEL); | 2335 | drv->state = kzalloc(sizeof(struct uart_state) * drv->nr, GFP_KERNEL); |
2334 | retval = -ENOMEM; | ||
2335 | if (!drv->state) | 2336 | if (!drv->state) |
2336 | goto out; | 2337 | goto out; |
2337 | 2338 | ||
2338 | normal = alloc_tty_driver(drv->nr); | 2339 | normal = alloc_tty_driver(drv->nr); |
2339 | if (!normal) | 2340 | if (!normal) |
2340 | goto out; | 2341 | goto out_kfree; |
2341 | 2342 | ||
2342 | drv->tty_driver = normal; | 2343 | drv->tty_driver = normal; |
2343 | 2344 | ||
@@ -2360,24 +2361,25 @@ int uart_register_driver(struct uart_driver *drv) | |||
2360 | */ | 2361 | */ |
2361 | for (i = 0; i < drv->nr; i++) { | 2362 | for (i = 0; i < drv->nr; i++) { |
2362 | struct uart_state *state = drv->state + i; | 2363 | struct uart_state *state = drv->state + i; |
2364 | struct tty_port *port = &state->port; | ||
2363 | 2365 | ||
2364 | state->close_delay = 500; /* .5 seconds */ | 2366 | tty_port_init(port); |
2365 | state->closing_wait = 30000; /* 30 seconds */ | 2367 | port->ops = &uart_port_ops; |
2366 | mutex_init(&state->mutex); | 2368 | port->close_delay = 500; /* .5 seconds */ |
2367 | 2369 | port->closing_wait = 30000; /* 30 seconds */ | |
2368 | tty_port_init(&state->info.port); | 2370 | tasklet_init(&state->tlet, uart_tasklet_action, |
2369 | init_waitqueue_head(&state->info.delta_msr_wait); | ||
2370 | tasklet_init(&state->info.tlet, uart_tasklet_action, | ||
2371 | (unsigned long)state); | 2371 | (unsigned long)state); |
2372 | } | 2372 | } |
2373 | 2373 | ||
2374 | retval = tty_register_driver(normal); | 2374 | retval = tty_register_driver(normal); |
2375 | out: | 2375 | if (retval >= 0) |
2376 | if (retval < 0) { | 2376 | return retval; |
2377 | put_tty_driver(normal); | 2377 | |
2378 | kfree(drv->state); | 2378 | put_tty_driver(normal); |
2379 | } | 2379 | out_kfree: |
2380 | return retval; | 2380 | kfree(drv->state); |
2381 | out: | ||
2382 | return -ENOMEM; | ||
2381 | } | 2383 | } |
2382 | 2384 | ||
2383 | /** | 2385 | /** |
@@ -2408,69 +2410,71 @@ struct tty_driver *uart_console_device(struct console *co, int *index) | |||
2408 | /** | 2410 | /** |
2409 | * uart_add_one_port - attach a driver-defined port structure | 2411 | * uart_add_one_port - attach a driver-defined port structure |
2410 | * @drv: pointer to the uart low level driver structure for this port | 2412 | * @drv: pointer to the uart low level driver structure for this port |
2411 | * @port: uart port structure to use for this port. | 2413 | * @uport: uart port structure to use for this port. |
2412 | * | 2414 | * |
2413 | * This allows the driver to register its own uart_port structure | 2415 | * This allows the driver to register its own uart_port structure |
2414 | * with the core driver. The main purpose is to allow the low | 2416 | * with the core driver. The main purpose is to allow the low |
2415 | * level uart drivers to expand uart_port, rather than having yet | 2417 | * level uart drivers to expand uart_port, rather than having yet |
2416 | * more levels of structures. | 2418 | * more levels of structures. |
2417 | */ | 2419 | */ |
2418 | int uart_add_one_port(struct uart_driver *drv, struct uart_port *port) | 2420 | int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) |
2419 | { | 2421 | { |
2420 | struct uart_state *state; | 2422 | struct uart_state *state; |
2423 | struct tty_port *port; | ||
2421 | int ret = 0; | 2424 | int ret = 0; |
2422 | struct device *tty_dev; | 2425 | struct device *tty_dev; |
2423 | 2426 | ||
2424 | BUG_ON(in_interrupt()); | 2427 | BUG_ON(in_interrupt()); |
2425 | 2428 | ||
2426 | if (port->line >= drv->nr) | 2429 | if (uport->line >= drv->nr) |
2427 | return -EINVAL; | 2430 | return -EINVAL; |
2428 | 2431 | ||
2429 | state = drv->state + port->line; | 2432 | state = drv->state + uport->line; |
2433 | port = &state->port; | ||
2430 | 2434 | ||
2431 | mutex_lock(&port_mutex); | 2435 | mutex_lock(&port_mutex); |
2432 | mutex_lock(&state->mutex); | 2436 | mutex_lock(&port->mutex); |
2433 | if (state->port) { | 2437 | if (state->uart_port) { |
2434 | ret = -EINVAL; | 2438 | ret = -EINVAL; |
2435 | goto out; | 2439 | goto out; |
2436 | } | 2440 | } |
2437 | 2441 | ||
2438 | state->port = port; | 2442 | state->uart_port = uport; |
2439 | state->pm_state = -1; | 2443 | state->pm_state = -1; |
2440 | 2444 | ||
2441 | port->cons = drv->cons; | 2445 | uport->cons = drv->cons; |
2442 | port->info = &state->info; | 2446 | uport->state = state; |
2443 | 2447 | ||
2444 | /* | 2448 | /* |
2445 | * If this port is a console, then the spinlock is already | 2449 | * If this port is a console, then the spinlock is already |
2446 | * initialised. | 2450 | * initialised. |
2447 | */ | 2451 | */ |
2448 | if (!(uart_console(port) && (port->cons->flags & CON_ENABLED))) { | 2452 | if (!(uart_console(uport) && (uport->cons->flags & CON_ENABLED))) { |
2449 | spin_lock_init(&port->lock); | 2453 | spin_lock_init(&uport->lock); |
2450 | lockdep_set_class(&port->lock, &port_lock_key); | 2454 | lockdep_set_class(&uport->lock, &port_lock_key); |
2451 | } | 2455 | } |
2452 | 2456 | ||
2453 | uart_configure_port(drv, state, port); | 2457 | uart_configure_port(drv, state, uport); |
2454 | 2458 | ||
2455 | /* | 2459 | /* |
2456 | * Register the port whether it's detected or not. This allows | 2460 | * Register the port whether it's detected or not. This allows |
2457 | * setserial to be used to alter this ports parameters. | 2461 | * setserial to be used to alter this ports parameters. |
2458 | */ | 2462 | */ |
2459 | tty_dev = tty_register_device(drv->tty_driver, port->line, port->dev); | 2463 | tty_dev = tty_register_device(drv->tty_driver, uport->line, uport->dev); |
2460 | if (likely(!IS_ERR(tty_dev))) { | 2464 | if (likely(!IS_ERR(tty_dev))) { |
2461 | device_init_wakeup(tty_dev, 1); | 2465 | device_init_wakeup(tty_dev, 1); |
2462 | device_set_wakeup_enable(tty_dev, 0); | 2466 | device_set_wakeup_enable(tty_dev, 0); |
2463 | } else | 2467 | } else |
2464 | printk(KERN_ERR "Cannot register tty device on line %d\n", | 2468 | printk(KERN_ERR "Cannot register tty device on line %d\n", |
2465 | port->line); | 2469 | uport->line); |
2466 | 2470 | ||
2467 | /* | 2471 | /* |
2468 | * Ensure UPF_DEAD is not set. | 2472 | * Ensure UPF_DEAD is not set. |
2469 | */ | 2473 | */ |
2470 | port->flags &= ~UPF_DEAD; | 2474 | uport->flags &= ~UPF_DEAD; |
2471 | 2475 | ||
2472 | out: | 2476 | out: |
2473 | mutex_unlock(&state->mutex); | 2477 | mutex_unlock(&port->mutex); |
2474 | mutex_unlock(&port_mutex); | 2478 | mutex_unlock(&port_mutex); |
2475 | 2479 | ||
2476 | return ret; | 2480 | return ret; |
@@ -2479,22 +2483,22 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port) | |||
2479 | /** | 2483 | /** |
2480 | * uart_remove_one_port - detach a driver defined port structure | 2484 | * uart_remove_one_port - detach a driver defined port structure |
2481 | * @drv: pointer to the uart low level driver structure for this port | 2485 | * @drv: pointer to the uart low level driver structure for this port |
2482 | * @port: uart port structure for this port | 2486 | * @uport: uart port structure for this port |
2483 | * | 2487 | * |
2484 | * This unhooks (and hangs up) the specified port structure from the | 2488 | * This unhooks (and hangs up) the specified port structure from the |
2485 | * core driver. No further calls will be made to the low-level code | 2489 | * core driver. No further calls will be made to the low-level code |
2486 | * for this port. | 2490 | * for this port. |
2487 | */ | 2491 | */ |
2488 | int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port) | 2492 | int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport) |
2489 | { | 2493 | { |
2490 | struct uart_state *state = drv->state + port->line; | 2494 | struct uart_state *state = drv->state + uport->line; |
2491 | struct uart_info *info; | 2495 | struct tty_port *port = &state->port; |
2492 | 2496 | ||
2493 | BUG_ON(in_interrupt()); | 2497 | BUG_ON(in_interrupt()); |
2494 | 2498 | ||
2495 | if (state->port != port) | 2499 | if (state->uart_port != uport) |
2496 | printk(KERN_ALERT "Removing wrong port: %p != %p\n", | 2500 | printk(KERN_ALERT "Removing wrong port: %p != %p\n", |
2497 | state->port, port); | 2501 | state->uart_port, uport); |
2498 | 2502 | ||
2499 | mutex_lock(&port_mutex); | 2503 | mutex_lock(&port_mutex); |
2500 | 2504 | ||
@@ -2502,37 +2506,35 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port) | |||
2502 | * Mark the port "dead" - this prevents any opens from | 2506 | * Mark the port "dead" - this prevents any opens from |
2503 | * succeeding while we shut down the port. | 2507 | * succeeding while we shut down the port. |
2504 | */ | 2508 | */ |
2505 | mutex_lock(&state->mutex); | 2509 | mutex_lock(&port->mutex); |
2506 | port->flags |= UPF_DEAD; | 2510 | uport->flags |= UPF_DEAD; |
2507 | mutex_unlock(&state->mutex); | 2511 | mutex_unlock(&port->mutex); |
2508 | 2512 | ||
2509 | /* | 2513 | /* |
2510 | * Remove the devices from the tty layer | 2514 | * Remove the devices from the tty layer |
2511 | */ | 2515 | */ |
2512 | tty_unregister_device(drv->tty_driver, port->line); | 2516 | tty_unregister_device(drv->tty_driver, uport->line); |
2513 | 2517 | ||
2514 | info = &state->info; | 2518 | if (port->tty) |
2515 | if (info && info->port.tty) | 2519 | tty_vhangup(port->tty); |
2516 | tty_vhangup(info->port.tty); | ||
2517 | 2520 | ||
2518 | /* | 2521 | /* |
2519 | * Free the port IO and memory resources, if any. | 2522 | * Free the port IO and memory resources, if any. |
2520 | */ | 2523 | */ |
2521 | if (port->type != PORT_UNKNOWN) | 2524 | if (uport->type != PORT_UNKNOWN) |
2522 | port->ops->release_port(port); | 2525 | uport->ops->release_port(uport); |
2523 | 2526 | ||
2524 | /* | 2527 | /* |
2525 | * Indicate that there isn't a port here anymore. | 2528 | * Indicate that there isn't a port here anymore. |
2526 | */ | 2529 | */ |
2527 | port->type = PORT_UNKNOWN; | 2530 | uport->type = PORT_UNKNOWN; |
2528 | 2531 | ||
2529 | /* | 2532 | /* |
2530 | * Kill the tasklet, and free resources. | 2533 | * Kill the tasklet, and free resources. |
2531 | */ | 2534 | */ |
2532 | if (info) | 2535 | tasklet_kill(&state->tlet); |
2533 | tasklet_kill(&info->tlet); | ||
2534 | 2536 | ||
2535 | state->port = NULL; | 2537 | state->uart_port = NULL; |
2536 | mutex_unlock(&port_mutex); | 2538 | mutex_unlock(&port_mutex); |
2537 | 2539 | ||
2538 | return 0; | 2540 | return 0; |
@@ -2557,6 +2559,7 @@ int uart_match_port(struct uart_port *port1, struct uart_port *port2) | |||
2557 | case UPIO_AU: | 2559 | case UPIO_AU: |
2558 | case UPIO_TSI: | 2560 | case UPIO_TSI: |
2559 | case UPIO_DWAPB: | 2561 | case UPIO_DWAPB: |
2562 | case UPIO_DWAPB32: | ||
2560 | return (port1->mapbase == port2->mapbase); | 2563 | return (port1->mapbase == port2->mapbase); |
2561 | } | 2564 | } |
2562 | return 0; | 2565 | return 0; |
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index 79c9c5f5cdba..93760b2ea172 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c | |||
@@ -45,8 +45,6 @@ | |||
45 | #include <asm/io.h> | 45 | #include <asm/io.h> |
46 | #include <asm/system.h> | 46 | #include <asm/system.h> |
47 | 47 | ||
48 | #include <pcmcia/cs_types.h> | ||
49 | #include <pcmcia/cs.h> | ||
50 | #include <pcmcia/cistpl.h> | 48 | #include <pcmcia/cistpl.h> |
51 | #include <pcmcia/ciscode.h> | 49 | #include <pcmcia/ciscode.h> |
52 | #include <pcmcia/ds.h> | 50 | #include <pcmcia/ds.h> |
@@ -54,14 +52,6 @@ | |||
54 | 52 | ||
55 | #include "8250.h" | 53 | #include "8250.h" |
56 | 54 | ||
57 | #ifdef PCMCIA_DEBUG | ||
58 | static int pc_debug = PCMCIA_DEBUG; | ||
59 | module_param(pc_debug, int, 0644); | ||
60 | #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) | ||
61 | static char *version = "serial_cs.c 1.134 2002/05/04 05:48:53 (David Hinds)"; | ||
62 | #else | ||
63 | #define DEBUG(n, args...) | ||
64 | #endif | ||
65 | 55 | ||
66 | /*====================================================================*/ | 56 | /*====================================================================*/ |
67 | 57 | ||
@@ -97,7 +87,6 @@ struct serial_info { | |||
97 | int manfid; | 87 | int manfid; |
98 | int prodid; | 88 | int prodid; |
99 | int c950ctrl; | 89 | int c950ctrl; |
100 | dev_node_t node[4]; | ||
101 | int line[4]; | 90 | int line[4]; |
102 | const struct serial_quirk *quirk; | 91 | const struct serial_quirk *quirk; |
103 | }; | 92 | }; |
@@ -113,6 +102,10 @@ struct serial_cfg_mem { | |||
113 | * manfid 0x0160, 0x0104 | 102 | * manfid 0x0160, 0x0104 |
114 | * This card appears to have a 14.7456MHz clock. | 103 | * This card appears to have a 14.7456MHz clock. |
115 | */ | 104 | */ |
105 | /* Generic Modem: MD55x (GPRS/EDGE) have | ||
106 | * Elan VPU16551 UART with 14.7456MHz oscillator | ||
107 | * manfid 0x015D, 0x4C45 | ||
108 | */ | ||
116 | static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_port *port) | 109 | static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_port *port) |
117 | { | 110 | { |
118 | port->uartclk = 14745600; | 111 | port->uartclk = 14745600; |
@@ -120,25 +113,19 @@ static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_ | |||
120 | 113 | ||
121 | static int quirk_post_ibm(struct pcmcia_device *link) | 114 | static int quirk_post_ibm(struct pcmcia_device *link) |
122 | { | 115 | { |
123 | conf_reg_t reg = { 0, CS_READ, 0x800, 0 }; | 116 | u8 val; |
124 | int last_ret, last_fn; | 117 | int ret; |
125 | 118 | ||
126 | last_ret = pcmcia_access_configuration_register(link, ®); | 119 | ret = pcmcia_read_config_byte(link, 0x800, &val); |
127 | if (last_ret) { | 120 | if (ret) |
128 | last_fn = AccessConfigurationRegister; | 121 | goto failed; |
129 | goto cs_failed; | 122 | |
130 | } | 123 | ret = pcmcia_write_config_byte(link, 0x800, val | 1); |
131 | reg.Action = CS_WRITE; | 124 | if (ret) |
132 | reg.Value = reg.Value | 1; | 125 | goto failed; |
133 | last_ret = pcmcia_access_configuration_register(link, ®); | ||
134 | if (last_ret) { | ||
135 | last_fn = AccessConfigurationRegister; | ||
136 | goto cs_failed; | ||
137 | } | ||
138 | return 0; | 126 | return 0; |
139 | 127 | ||
140 | cs_failed: | 128 | failed: |
141 | cs_error(link, last_fn, last_ret); | ||
142 | return -ENODEV; | 129 | return -ENODEV; |
143 | } | 130 | } |
144 | 131 | ||
@@ -158,7 +145,8 @@ static void quirk_wakeup_oxsemi(struct pcmcia_device *link) | |||
158 | { | 145 | { |
159 | struct serial_info *info = link->priv; | 146 | struct serial_info *info = link->priv; |
160 | 147 | ||
161 | outb(12, info->c950ctrl + 1); | 148 | if (info->c950ctrl) |
149 | outb(12, info->c950ctrl + 1); | ||
162 | } | 150 | } |
163 | 151 | ||
164 | /* request_region? oxsemi branch does no request_region too... */ | 152 | /* request_region? oxsemi branch does no request_region too... */ |
@@ -194,10 +182,8 @@ static void quirk_config_socket(struct pcmcia_device *link) | |||
194 | { | 182 | { |
195 | struct serial_info *info = link->priv; | 183 | struct serial_info *info = link->priv; |
196 | 184 | ||
197 | if (info->multi) { | 185 | if (info->multi) |
198 | link->conf.Present |= PRESENT_EXT_STATUS; | 186 | link->config_flags |= CONF_ENABLE_ESR; |
199 | link->conf.ExtStatus = ESR_REQ_ATTN_ENA; | ||
200 | } | ||
201 | } | 187 | } |
202 | 188 | ||
203 | static const struct serial_quirk quirks[] = { | 189 | static const struct serial_quirk quirks[] = { |
@@ -207,6 +193,11 @@ static const struct serial_quirk quirks[] = { | |||
207 | .multi = -1, | 193 | .multi = -1, |
208 | .setup = quirk_setup_brainboxes_0104, | 194 | .setup = quirk_setup_brainboxes_0104, |
209 | }, { | 195 | }, { |
196 | .manfid = 0x015D, | ||
197 | .prodid = 0x4C45, | ||
198 | .multi = -1, | ||
199 | .setup = quirk_setup_brainboxes_0104, | ||
200 | }, { | ||
210 | .manfid = MANFID_IBM, | 201 | .manfid = MANFID_IBM, |
211 | .prodid = ~0, | 202 | .prodid = ~0, |
212 | .multi = -1, | 203 | .multi = -1, |
@@ -271,19 +262,12 @@ static const struct serial_quirk quirks[] = { | |||
271 | static int serial_config(struct pcmcia_device * link); | 262 | static int serial_config(struct pcmcia_device * link); |
272 | 263 | ||
273 | 264 | ||
274 | /*====================================================================== | ||
275 | |||
276 | After a card is removed, serial_remove() will unregister | ||
277 | the serial device(s), and release the PCMCIA configuration. | ||
278 | |||
279 | ======================================================================*/ | ||
280 | |||
281 | static void serial_remove(struct pcmcia_device *link) | 265 | static void serial_remove(struct pcmcia_device *link) |
282 | { | 266 | { |
283 | struct serial_info *info = link->priv; | 267 | struct serial_info *info = link->priv; |
284 | int i; | 268 | int i; |
285 | 269 | ||
286 | DEBUG(0, "serial_release(0x%p)\n", link); | 270 | dev_dbg(&link->dev, "serial_release\n"); |
287 | 271 | ||
288 | /* | 272 | /* |
289 | * Recheck to see if the device is still configured. | 273 | * Recheck to see if the device is still configured. |
@@ -291,8 +275,6 @@ static void serial_remove(struct pcmcia_device *link) | |||
291 | for (i = 0; i < info->ndev; i++) | 275 | for (i = 0; i < info->ndev; i++) |
292 | serial8250_unregister_port(info->line[i]); | 276 | serial8250_unregister_port(info->line[i]); |
293 | 277 | ||
294 | info->p_dev->dev_node = NULL; | ||
295 | |||
296 | if (!info->slave) | 278 | if (!info->slave) |
297 | pcmcia_disable_device(link); | 279 | pcmcia_disable_device(link); |
298 | } | 280 | } |
@@ -322,19 +304,11 @@ static int serial_resume(struct pcmcia_device *link) | |||
322 | return 0; | 304 | return 0; |
323 | } | 305 | } |
324 | 306 | ||
325 | /*====================================================================== | ||
326 | |||
327 | serial_attach() creates an "instance" of the driver, allocating | ||
328 | local data structures for one device. The device is registered | ||
329 | with Card Services. | ||
330 | |||
331 | ======================================================================*/ | ||
332 | |||
333 | static int serial_probe(struct pcmcia_device *link) | 307 | static int serial_probe(struct pcmcia_device *link) |
334 | { | 308 | { |
335 | struct serial_info *info; | 309 | struct serial_info *info; |
336 | 310 | ||
337 | DEBUG(0, "serial_attach()\n"); | 311 | dev_dbg(&link->dev, "serial_attach()\n"); |
338 | 312 | ||
339 | /* Create new serial device */ | 313 | /* Create new serial device */ |
340 | info = kzalloc(sizeof (*info), GFP_KERNEL); | 314 | info = kzalloc(sizeof (*info), GFP_KERNEL); |
@@ -343,39 +317,18 @@ static int serial_probe(struct pcmcia_device *link) | |||
343 | info->p_dev = link; | 317 | info->p_dev = link; |
344 | link->priv = info; | 318 | link->priv = info; |
345 | 319 | ||
346 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | 320 | link->config_flags |= CONF_ENABLE_IRQ; |
347 | link->io.NumPorts1 = 8; | 321 | if (do_sound) |
348 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | 322 | link->config_flags |= CONF_ENABLE_SPKR; |
349 | link->irq.IRQInfo1 = IRQ_LEVEL_ID; | ||
350 | link->conf.Attributes = CONF_ENABLE_IRQ; | ||
351 | if (do_sound) { | ||
352 | link->conf.Attributes |= CONF_ENABLE_SPKR; | ||
353 | link->conf.Status = CCSR_AUDIO_ENA; | ||
354 | } | ||
355 | link->conf.IntType = INT_MEMORY_AND_IO; | ||
356 | 323 | ||
357 | return serial_config(link); | 324 | return serial_config(link); |
358 | } | 325 | } |
359 | 326 | ||
360 | /*====================================================================== | ||
361 | |||
362 | This deletes a driver "instance". The device is de-registered | ||
363 | with Card Services. If it has been released, all local data | ||
364 | structures are freed. Otherwise, the structures will be freed | ||
365 | when the device is released. | ||
366 | |||
367 | ======================================================================*/ | ||
368 | |||
369 | static void serial_detach(struct pcmcia_device *link) | 327 | static void serial_detach(struct pcmcia_device *link) |
370 | { | 328 | { |
371 | struct serial_info *info = link->priv; | 329 | struct serial_info *info = link->priv; |
372 | 330 | ||
373 | DEBUG(0, "serial_detach(0x%p)\n", link); | 331 | dev_dbg(&link->dev, "serial_detach\n"); |
374 | |||
375 | /* | ||
376 | * Ensure any outstanding scheduled tasks are completed. | ||
377 | */ | ||
378 | flush_scheduled_work(); | ||
379 | 332 | ||
380 | /* | 333 | /* |
381 | * Ensure that the ports have been released. | 334 | * Ensure that the ports have been released. |
@@ -399,7 +352,7 @@ static int setup_serial(struct pcmcia_device *handle, struct serial_info * info, | |||
399 | port.irq = irq; | 352 | port.irq = irq; |
400 | port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ; | 353 | port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ; |
401 | port.uartclk = 1843200; | 354 | port.uartclk = 1843200; |
402 | port.dev = &handle_to_dev(handle); | 355 | port.dev = &handle->dev; |
403 | if (buggy_uart) | 356 | if (buggy_uart) |
404 | port.flags |= UPF_BUGGY_UART; | 357 | port.flags |= UPF_BUGGY_UART; |
405 | 358 | ||
@@ -414,11 +367,6 @@ static int setup_serial(struct pcmcia_device *handle, struct serial_info * info, | |||
414 | } | 367 | } |
415 | 368 | ||
416 | info->line[info->ndev] = line; | 369 | info->line[info->ndev] = line; |
417 | sprintf(info->node[info->ndev].dev_name, "ttyS%d", line); | ||
418 | info->node[info->ndev].major = TTY_MAJOR; | ||
419 | info->node[info->ndev].minor = 0x40 + line; | ||
420 | if (info->ndev > 0) | ||
421 | info->node[info->ndev - 1].next = &info->node[info->ndev]; | ||
422 | info->ndev++; | 370 | info->ndev++; |
423 | 371 | ||
424 | return 0; | 372 | return 0; |
@@ -426,61 +374,66 @@ static int setup_serial(struct pcmcia_device *handle, struct serial_info * info, | |||
426 | 374 | ||
427 | /*====================================================================*/ | 375 | /*====================================================================*/ |
428 | 376 | ||
429 | static int | 377 | static int pfc_config(struct pcmcia_device *p_dev) |
430 | first_tuple(struct pcmcia_device *handle, tuple_t * tuple, cisparse_t * parse) | ||
431 | { | 378 | { |
432 | int i; | 379 | unsigned int port = 0; |
433 | i = pcmcia_get_first_tuple(handle, tuple); | 380 | struct serial_info *info = p_dev->priv; |
434 | if (i != 0) | 381 | |
435 | return i; | 382 | if ((p_dev->resource[1]->end != 0) && |
436 | i = pcmcia_get_tuple_data(handle, tuple); | 383 | (resource_size(p_dev->resource[1]) == 8)) { |
437 | if (i != 0) | 384 | port = p_dev->resource[1]->start; |
438 | return i; | 385 | info->slave = 1; |
439 | return pcmcia_parse_tuple(tuple, parse); | 386 | } else if ((info->manfid == MANFID_OSITECH) && |
440 | } | 387 | (resource_size(p_dev->resource[0]) == 0x40)) { |
388 | port = p_dev->resource[0]->start + 0x28; | ||
389 | info->slave = 1; | ||
390 | } | ||
391 | if (info->slave) | ||
392 | return setup_serial(p_dev, info, port, p_dev->irq); | ||
441 | 393 | ||
442 | /*====================================================================*/ | 394 | dev_warn(&p_dev->dev, "no usable port range found, giving up\n"); |
395 | return -ENODEV; | ||
396 | } | ||
443 | 397 | ||
444 | static int simple_config_check(struct pcmcia_device *p_dev, | 398 | static int simple_config_check(struct pcmcia_device *p_dev, void *priv_data) |
445 | cistpl_cftable_entry_t *cf, | ||
446 | cistpl_cftable_entry_t *dflt, | ||
447 | unsigned int vcc, | ||
448 | void *priv_data) | ||
449 | { | 399 | { |
450 | static const int size_table[2] = { 8, 16 }; | 400 | static const int size_table[2] = { 8, 16 }; |
451 | int *try = priv_data; | 401 | int *try = priv_data; |
452 | 402 | ||
453 | if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) | 403 | if (p_dev->resource[0]->start == 0) |
454 | p_dev->conf.Vpp = | 404 | return -ENODEV; |
455 | cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; | 405 | |
406 | if ((*try & 0x1) == 0) | ||
407 | p_dev->io_lines = 16; | ||
456 | 408 | ||
457 | if ((cf->io.nwin > 0) && (cf->io.win[0].len == size_table[(*try >> 1)]) | 409 | if (p_dev->resource[0]->end != size_table[(*try >> 1)]) |
458 | && (cf->io.win[0].base != 0)) { | 410 | return -ENODEV; |
459 | p_dev->io.BasePort1 = cf->io.win[0].base; | 411 | |
460 | p_dev->io.IOAddrLines = ((*try & 0x1) == 0) ? | 412 | p_dev->resource[0]->end = 8; |
461 | 16 : cf->io.flags & CISTPL_IO_LINES_MASK; | 413 | p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; |
462 | if (!pcmcia_request_io(p_dev, &p_dev->io)) | 414 | p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; |
463 | return 0; | 415 | |
464 | } | 416 | return pcmcia_request_io(p_dev); |
465 | return -EINVAL; | ||
466 | } | 417 | } |
467 | 418 | ||
468 | static int simple_config_check_notpicky(struct pcmcia_device *p_dev, | 419 | static int simple_config_check_notpicky(struct pcmcia_device *p_dev, |
469 | cistpl_cftable_entry_t *cf, | ||
470 | cistpl_cftable_entry_t *dflt, | ||
471 | unsigned int vcc, | ||
472 | void *priv_data) | 420 | void *priv_data) |
473 | { | 421 | { |
474 | static const unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; | 422 | static const unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; |
475 | int j; | 423 | int j; |
476 | 424 | ||
477 | if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { | 425 | if (p_dev->io_lines > 3) |
478 | for (j = 0; j < 5; j++) { | 426 | return -ENODEV; |
479 | p_dev->io.BasePort1 = base[j]; | 427 | |
480 | p_dev->io.IOAddrLines = base[j] ? 16 : 3; | 428 | p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; |
481 | if (!pcmcia_request_io(p_dev, &p_dev->io)) | 429 | p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; |
482 | return 0; | 430 | p_dev->resource[0]->end = 8; |
483 | } | 431 | |
432 | for (j = 0; j < 5; j++) { | ||
433 | p_dev->resource[0]->start = base[j]; | ||
434 | p_dev->io_lines = base[j] ? 16 : 3; | ||
435 | if (!pcmcia_request_io(p_dev)) | ||
436 | return 0; | ||
484 | } | 437 | } |
485 | return -ENODEV; | 438 | return -ENODEV; |
486 | } | 439 | } |
@@ -490,26 +443,9 @@ static int simple_config(struct pcmcia_device *link) | |||
490 | struct serial_info *info = link->priv; | 443 | struct serial_info *info = link->priv; |
491 | int i = -ENODEV, try; | 444 | int i = -ENODEV, try; |
492 | 445 | ||
493 | /* If the card is already configured, look up the port and irq */ | ||
494 | if (link->function_config) { | ||
495 | unsigned int port = 0; | ||
496 | if ((link->io.BasePort2 != 0) && | ||
497 | (link->io.NumPorts2 == 8)) { | ||
498 | port = link->io.BasePort2; | ||
499 | info->slave = 1; | ||
500 | } else if ((info->manfid == MANFID_OSITECH) && | ||
501 | (link->io.NumPorts1 == 0x40)) { | ||
502 | port = link->io.BasePort1 + 0x28; | ||
503 | info->slave = 1; | ||
504 | } | ||
505 | if (info->slave) { | ||
506 | return setup_serial(link, info, port, | ||
507 | link->irq.AssignedIRQ); | ||
508 | } | ||
509 | } | ||
510 | |||
511 | /* First pass: look for a config entry that looks normal. | 446 | /* First pass: look for a config entry that looks normal. |
512 | * Two tries: without IO aliases, then with aliases */ | 447 | * Two tries: without IO aliases, then with aliases */ |
448 | link->config_flags |= CONF_AUTO_SET_VPP | CONF_AUTO_SET_IO; | ||
513 | for (try = 0; try < 4; try++) | 449 | for (try = 0; try < 4; try++) |
514 | if (!pcmcia_loop_config(link, simple_config_check, &try)) | 450 | if (!pcmcia_loop_config(link, simple_config_check, &try)) |
515 | goto found_port; | 451 | goto found_port; |
@@ -520,19 +456,12 @@ static int simple_config(struct pcmcia_device *link) | |||
520 | if (!pcmcia_loop_config(link, simple_config_check_notpicky, NULL)) | 456 | if (!pcmcia_loop_config(link, simple_config_check_notpicky, NULL)) |
521 | goto found_port; | 457 | goto found_port; |
522 | 458 | ||
523 | printk(KERN_NOTICE | 459 | dev_warn(&link->dev, "no usable port range found, giving up\n"); |
524 | "serial_cs: no usable port range found, giving up\n"); | ||
525 | cs_error(link, RequestIO, i); | ||
526 | return -1; | 460 | return -1; |
527 | 461 | ||
528 | found_port: | 462 | found_port: |
529 | i = pcmcia_request_irq(link, &link->irq); | ||
530 | if (i != 0) { | ||
531 | cs_error(link, RequestIRQ, i); | ||
532 | link->irq.AssignedIRQ = 0; | ||
533 | } | ||
534 | if (info->multi && (info->manfid == MANFID_3COM)) | 463 | if (info->multi && (info->manfid == MANFID_3COM)) |
535 | link->conf.ConfigIndex &= ~(0x08); | 464 | link->config_index &= ~(0x08); |
536 | 465 | ||
537 | /* | 466 | /* |
538 | * Apply any configuration quirks. | 467 | * Apply any configuration quirks. |
@@ -540,53 +469,50 @@ found_port: | |||
540 | if (info->quirk && info->quirk->config) | 469 | if (info->quirk && info->quirk->config) |
541 | info->quirk->config(link); | 470 | info->quirk->config(link); |
542 | 471 | ||
543 | i = pcmcia_request_configuration(link, &link->conf); | 472 | i = pcmcia_enable_device(link); |
544 | if (i != 0) { | 473 | if (i != 0) |
545 | cs_error(link, RequestConfiguration, i); | ||
546 | return -1; | 474 | return -1; |
547 | } | 475 | return setup_serial(link, info, link->resource[0]->start, link->irq); |
548 | return setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ); | ||
549 | } | 476 | } |
550 | 477 | ||
551 | static int multi_config_check(struct pcmcia_device *p_dev, | 478 | static int multi_config_check(struct pcmcia_device *p_dev, void *priv_data) |
552 | cistpl_cftable_entry_t *cf, | ||
553 | cistpl_cftable_entry_t *dflt, | ||
554 | unsigned int vcc, | ||
555 | void *priv_data) | ||
556 | { | 479 | { |
557 | int *base2 = priv_data; | 480 | int *multi = priv_data; |
481 | |||
482 | if (p_dev->resource[1]->end) | ||
483 | return -EINVAL; | ||
558 | 484 | ||
559 | /* The quad port cards have bad CIS's, so just look for a | 485 | /* The quad port cards have bad CIS's, so just look for a |
560 | window larger than 8 ports and assume it will be right */ | 486 | window larger than 8 ports and assume it will be right */ |
561 | if ((cf->io.nwin == 1) && (cf->io.win[0].len > 8)) { | 487 | if (p_dev->resource[0]->end <= 8) |
562 | p_dev->io.BasePort1 = cf->io.win[0].base; | 488 | return -EINVAL; |
563 | p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; | 489 | |
564 | if (!pcmcia_request_io(p_dev, &p_dev->io)) { | 490 | p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; |
565 | *base2 = p_dev->io.BasePort1 + 8; | 491 | p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; |
566 | return 0; | 492 | p_dev->resource[0]->end = *multi * 8; |
567 | } | 493 | |
568 | } | 494 | if (pcmcia_request_io(p_dev)) |
569 | return -ENODEV; | 495 | return -ENODEV; |
496 | return 0; | ||
570 | } | 497 | } |
571 | 498 | ||
572 | static int multi_config_check_notpicky(struct pcmcia_device *p_dev, | 499 | static int multi_config_check_notpicky(struct pcmcia_device *p_dev, |
573 | cistpl_cftable_entry_t *cf, | ||
574 | cistpl_cftable_entry_t *dflt, | ||
575 | unsigned int vcc, | ||
576 | void *priv_data) | 500 | void *priv_data) |
577 | { | 501 | { |
578 | int *base2 = priv_data; | 502 | int *base2 = priv_data; |
579 | 503 | ||
580 | if (cf->io.nwin == 2) { | 504 | if (!p_dev->resource[0]->end || !p_dev->resource[1]->end) |
581 | p_dev->io.BasePort1 = cf->io.win[0].base; | 505 | return -ENODEV; |
582 | p_dev->io.BasePort2 = cf->io.win[1].base; | 506 | |
583 | p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; | 507 | p_dev->resource[0]->end = p_dev->resource[1]->end = 8; |
584 | if (!pcmcia_request_io(p_dev, &p_dev->io)) { | 508 | p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; |
585 | *base2 = p_dev->io.BasePort2; | 509 | p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; |
586 | return 0; | 510 | |
587 | } | 511 | if (pcmcia_request_io(p_dev)) |
588 | } | 512 | return -ENODEV; |
589 | return -ENODEV; | 513 | |
514 | *base2 = p_dev->resource[0]->start + 8; | ||
515 | return 0; | ||
590 | } | 516 | } |
591 | 517 | ||
592 | static int multi_config(struct pcmcia_device *link) | 518 | static int multi_config(struct pcmcia_device *link) |
@@ -594,28 +520,23 @@ static int multi_config(struct pcmcia_device *link) | |||
594 | struct serial_info *info = link->priv; | 520 | struct serial_info *info = link->priv; |
595 | int i, base2 = 0; | 521 | int i, base2 = 0; |
596 | 522 | ||
523 | link->config_flags |= CONF_AUTO_SET_IO; | ||
597 | /* First, look for a generic full-sized window */ | 524 | /* First, look for a generic full-sized window */ |
598 | link->io.NumPorts1 = info->multi * 8; | 525 | if (!pcmcia_loop_config(link, multi_config_check, &info->multi)) |
599 | if (pcmcia_loop_config(link, multi_config_check, &base2)) { | 526 | base2 = link->resource[0]->start + 8; |
527 | else { | ||
600 | /* If that didn't work, look for two windows */ | 528 | /* If that didn't work, look for two windows */ |
601 | link->io.NumPorts1 = link->io.NumPorts2 = 8; | ||
602 | info->multi = 2; | 529 | info->multi = 2; |
603 | if (pcmcia_loop_config(link, multi_config_check_notpicky, | 530 | if (pcmcia_loop_config(link, multi_config_check_notpicky, |
604 | &base2)) { | 531 | &base2)) { |
605 | printk(KERN_NOTICE "serial_cs: no usable port range" | 532 | dev_warn(&link->dev, "no usable port range " |
606 | "found, giving up\n"); | 533 | "found, giving up\n"); |
607 | return -ENODEV; | 534 | return -ENODEV; |
608 | } | 535 | } |
609 | } | 536 | } |
610 | 537 | ||
611 | i = pcmcia_request_irq(link, &link->irq); | 538 | if (!link->irq) |
612 | if (i != 0) { | 539 | dev_warn(&link->dev, "no usable IRQ found, continuing...\n"); |
613 | /* FIXME: comment does not fit, error handling does not fit */ | ||
614 | printk(KERN_NOTICE | ||
615 | "serial_cs: no usable port range found, giving up\n"); | ||
616 | cs_error(link, RequestIRQ, i); | ||
617 | link->irq.AssignedIRQ = 0; | ||
618 | } | ||
619 | 540 | ||
620 | /* | 541 | /* |
621 | * Apply any configuration quirks. | 542 | * Apply any configuration quirks. |
@@ -623,11 +544,9 @@ static int multi_config(struct pcmcia_device *link) | |||
623 | if (info->quirk && info->quirk->config) | 544 | if (info->quirk && info->quirk->config) |
624 | info->quirk->config(link); | 545 | info->quirk->config(link); |
625 | 546 | ||
626 | i = pcmcia_request_configuration(link, &link->conf); | 547 | i = pcmcia_enable_device(link); |
627 | if (i != 0) { | 548 | if (i != 0) |
628 | cs_error(link, RequestConfiguration, i); | ||
629 | return -ENODEV; | 549 | return -ENODEV; |
630 | } | ||
631 | 550 | ||
632 | /* The Oxford Semiconductor OXCF950 cards are in fact single-port: | 551 | /* The Oxford Semiconductor OXCF950 cards are in fact single-port: |
633 | * 8 registers are for the UART, the others are extra registers. | 552 | * 8 registers are for the UART, the others are extra registers. |
@@ -637,14 +556,14 @@ static int multi_config(struct pcmcia_device *link) | |||
637 | info->prodid == PRODID_POSSIO_GCC)) { | 556 | info->prodid == PRODID_POSSIO_GCC)) { |
638 | int err; | 557 | int err; |
639 | 558 | ||
640 | if (link->conf.ConfigIndex == 1 || | 559 | if (link->config_index == 1 || |
641 | link->conf.ConfigIndex == 3) { | 560 | link->config_index == 3) { |
642 | err = setup_serial(link, info, base2, | 561 | err = setup_serial(link, info, base2, |
643 | link->irq.AssignedIRQ); | 562 | link->irq); |
644 | base2 = link->io.BasePort1; | 563 | base2 = link->resource[0]->start; |
645 | } else { | 564 | } else { |
646 | err = setup_serial(link, info, link->io.BasePort1, | 565 | err = setup_serial(link, info, link->resource[0]->start, |
647 | link->irq.AssignedIRQ); | 566 | link->irq); |
648 | } | 567 | } |
649 | info->c950ctrl = base2; | 568 | info->c950ctrl = base2; |
650 | 569 | ||
@@ -658,64 +577,42 @@ static int multi_config(struct pcmcia_device *link) | |||
658 | return 0; | 577 | return 0; |
659 | } | 578 | } |
660 | 579 | ||
661 | setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ); | 580 | setup_serial(link, info, link->resource[0]->start, link->irq); |
662 | for (i = 0; i < info->multi - 1; i++) | 581 | for (i = 0; i < info->multi - 1; i++) |
663 | setup_serial(link, info, base2 + (8 * i), | 582 | setup_serial(link, info, base2 + (8 * i), |
664 | link->irq.AssignedIRQ); | 583 | link->irq); |
665 | return 0; | 584 | return 0; |
666 | } | 585 | } |
667 | 586 | ||
668 | /*====================================================================== | 587 | static int serial_check_for_multi(struct pcmcia_device *p_dev, void *priv_data) |
588 | { | ||
589 | struct serial_info *info = p_dev->priv; | ||
669 | 590 | ||
670 | serial_config() is scheduled to run after a CARD_INSERTION event | 591 | if (!p_dev->resource[0]->end) |
671 | is received, to configure the PCMCIA socket, and to make the | 592 | return -EINVAL; |
672 | serial device available to the system. | 593 | |
594 | if ((!p_dev->resource[1]->end) && (p_dev->resource[0]->end % 8 == 0)) | ||
595 | info->multi = p_dev->resource[0]->end >> 3; | ||
596 | |||
597 | if ((p_dev->resource[1]->end) && (p_dev->resource[0]->end == 8) | ||
598 | && (p_dev->resource[1]->end == 8)) | ||
599 | info->multi = 2; | ||
600 | |||
601 | return 0; /* break */ | ||
602 | } | ||
673 | 603 | ||
674 | ======================================================================*/ | ||
675 | 604 | ||
676 | static int serial_config(struct pcmcia_device * link) | 605 | static int serial_config(struct pcmcia_device * link) |
677 | { | 606 | { |
678 | struct serial_info *info = link->priv; | 607 | struct serial_info *info = link->priv; |
679 | struct serial_cfg_mem *cfg_mem; | 608 | int i; |
680 | tuple_t *tuple; | ||
681 | u_char *buf; | ||
682 | cisparse_t *parse; | ||
683 | cistpl_cftable_entry_t *cf; | ||
684 | int i, last_ret, last_fn; | ||
685 | |||
686 | DEBUG(0, "serial_config(0x%p)\n", link); | ||
687 | 609 | ||
688 | cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL); | 610 | dev_dbg(&link->dev, "serial_config\n"); |
689 | if (!cfg_mem) | ||
690 | goto failed; | ||
691 | |||
692 | tuple = &cfg_mem->tuple; | ||
693 | parse = &cfg_mem->parse; | ||
694 | cf = &parse->cftable_entry; | ||
695 | buf = cfg_mem->buf; | ||
696 | |||
697 | tuple->TupleData = (cisdata_t *) buf; | ||
698 | tuple->TupleOffset = 0; | ||
699 | tuple->TupleDataMax = 255; | ||
700 | tuple->Attributes = 0; | ||
701 | |||
702 | /* Get configuration register information */ | ||
703 | tuple->DesiredTuple = CISTPL_CONFIG; | ||
704 | last_ret = first_tuple(link, tuple, parse); | ||
705 | if (last_ret != 0) { | ||
706 | last_fn = ParseTuple; | ||
707 | goto cs_failed; | ||
708 | } | ||
709 | link->conf.ConfigBase = parse->config.base; | ||
710 | link->conf.Present = parse->config.rmask[0]; | ||
711 | 611 | ||
712 | /* Is this a compliant multifunction card? */ | 612 | /* Is this a compliant multifunction card? */ |
713 | tuple->DesiredTuple = CISTPL_LONGLINK_MFC; | 613 | info->multi = (link->socket->functions > 1); |
714 | tuple->Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK; | ||
715 | info->multi = (first_tuple(link, tuple, parse) == 0); | ||
716 | 614 | ||
717 | /* Is this a multiport card? */ | 615 | /* Is this a multiport card? */ |
718 | tuple->DesiredTuple = CISTPL_MANFID; | ||
719 | info->manfid = link->manf_id; | 616 | info->manfid = link->manf_id; |
720 | info->prodid = link->card_id; | 617 | info->prodid = link->card_id; |
721 | 618 | ||
@@ -730,20 +627,12 @@ static int serial_config(struct pcmcia_device * link) | |||
730 | 627 | ||
731 | /* Another check for dual-serial cards: look for either serial or | 628 | /* Another check for dual-serial cards: look for either serial or |
732 | multifunction cards that ask for appropriate IO port ranges */ | 629 | multifunction cards that ask for appropriate IO port ranges */ |
733 | tuple->DesiredTuple = CISTPL_FUNCID; | ||
734 | if ((info->multi == 0) && | 630 | if ((info->multi == 0) && |
735 | (link->has_func_id) && | 631 | (link->has_func_id) && |
632 | (link->socket->pcmcia_pfc == 0) && | ||
736 | ((link->func_id == CISTPL_FUNCID_MULTI) || | 633 | ((link->func_id == CISTPL_FUNCID_MULTI) || |
737 | (link->func_id == CISTPL_FUNCID_SERIAL))) { | 634 | (link->func_id == CISTPL_FUNCID_SERIAL))) |
738 | tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; | 635 | pcmcia_loop_config(link, serial_check_for_multi, info); |
739 | if (first_tuple(link, tuple, parse) == 0) { | ||
740 | if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0)) | ||
741 | info->multi = cf->io.win[0].len >> 3; | ||
742 | if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) && | ||
743 | (cf->io.win[1].len == 8)) | ||
744 | info->multi = 2; | ||
745 | } | ||
746 | } | ||
747 | 636 | ||
748 | /* | 637 | /* |
749 | * Apply any multi-port quirk. | 638 | * Apply any multi-port quirk. |
@@ -751,12 +640,18 @@ static int serial_config(struct pcmcia_device * link) | |||
751 | if (info->quirk && info->quirk->multi != -1) | 640 | if (info->quirk && info->quirk->multi != -1) |
752 | info->multi = info->quirk->multi; | 641 | info->multi = info->quirk->multi; |
753 | 642 | ||
754 | if (info->multi > 1) | 643 | dev_info(&link->dev, |
755 | multi_config(link); | 644 | "trying to set up [0x%04x:0x%04x] (pfc: %d, multi: %d, quirk: %p)\n", |
645 | link->manf_id, link->card_id, | ||
646 | link->socket->pcmcia_pfc, info->multi, info->quirk); | ||
647 | if (link->socket->pcmcia_pfc) | ||
648 | i = pfc_config(link); | ||
649 | else if (info->multi > 1) | ||
650 | i = multi_config(link); | ||
756 | else | 651 | else |
757 | simple_config(link); | 652 | i = simple_config(link); |
758 | 653 | ||
759 | if (info->ndev == 0) | 654 | if (i || info->ndev == 0) |
760 | goto failed; | 655 | goto failed; |
761 | 656 | ||
762 | /* | 657 | /* |
@@ -767,15 +662,11 @@ static int serial_config(struct pcmcia_device * link) | |||
767 | if (info->quirk->post(link)) | 662 | if (info->quirk->post(link)) |
768 | goto failed; | 663 | goto failed; |
769 | 664 | ||
770 | link->dev_node = &info->node[0]; | ||
771 | kfree(cfg_mem); | ||
772 | return 0; | 665 | return 0; |
773 | 666 | ||
774 | cs_failed: | ||
775 | cs_error(link, last_fn, last_ret); | ||
776 | failed: | 667 | failed: |
668 | dev_warn(&link->dev, "failed to initialize\n"); | ||
777 | serial_remove(link); | 669 | serial_remove(link); |
778 | kfree(cfg_mem); | ||
779 | return -ENODEV; | 670 | return -ENODEV; |
780 | } | 671 | } |
781 | 672 | ||
@@ -783,6 +674,8 @@ static struct pcmcia_device_id serial_ids[] = { | |||
783 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0057, 0x0021), | 674 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0057, 0x0021), |
784 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0089, 0x110a), | 675 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0089, 0x110a), |
785 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0104, 0x000a), | 676 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0104, 0x000a), |
677 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0d0a), | ||
678 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0e0a), | ||
786 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0xea15), | 679 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0xea15), |
787 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0109, 0x0501), | 680 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0109, 0x0501), |
788 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0138, 0x110a), | 681 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0138, 0x110a), |
@@ -792,8 +685,6 @@ static struct pcmcia_device_id serial_ids[] = { | |||
792 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x016c, 0x0081), | 685 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x016c, 0x0081), |
793 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x021b, 0x0101), | 686 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x021b, 0x0101), |
794 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x08a1, 0xc0ab), | 687 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x08a1, 0xc0ab), |
795 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0d0a), | ||
796 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0e0a), | ||
797 | PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3288", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x04cd2988, 0x46a52d63), | 688 | PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3288", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x04cd2988, 0x46a52d63), |
798 | PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3336", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x0143b773, 0x46a52d63), | 689 | PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3336", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x0143b773, 0x46a52d63), |
799 | PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "EM1144T", "PCMCIA MODEM", 0xf510db04, 0x856d66c8, 0xbd6c43ef), | 690 | PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "EM1144T", "PCMCIA MODEM", 0xf510db04, 0x856d66c8, 0xbd6c43ef), |
@@ -804,6 +695,7 @@ static struct pcmcia_device_id serial_ids[] = { | |||
804 | PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "REM10", 0x2e3ee845, 0x76df1d29), | 695 | PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "REM10", 0x2e3ee845, 0x76df1d29), |
805 | PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "XEM5600", 0x2e3ee845, 0xf1403719), | 696 | PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "XEM5600", 0x2e3ee845, 0xf1403719), |
806 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4), | 697 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4), |
698 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "ATKK", "LM33-PCM-T", 0xba9eb7e2, 0x077c174e), | ||
807 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff), | 699 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff), |
808 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Gateway 2000", "XJEM3336", 0xdd9989be, 0x662c394c), | 700 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Gateway 2000", "XJEM3336", 0xdd9989be, 0x662c394c), |
809 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae), | 701 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae), |
@@ -818,6 +710,7 @@ static struct pcmcia_device_id serial_ids[] = { | |||
818 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f), | 710 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f), |
819 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed), | 711 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed), |
820 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet+Modem II", 0x2e3ee845, 0xeca401bf), | 712 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet+Modem II", 0x2e3ee845, 0xeca401bf), |
713 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0e01), | ||
821 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0a05), | 714 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0a05), |
822 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x1101), | 715 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x1101), |
823 | PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0104, 0x0070), | 716 | PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0104, 0x0070), |
@@ -834,17 +727,26 @@ static struct pcmcia_device_id serial_ids[] = { | |||
834 | PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x0276), | 727 | PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x0276), |
835 | PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0039), | 728 | PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0039), |
836 | PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0006), | 729 | PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0006), |
730 | PCMCIA_DEVICE_MANF_CARD(0x0105, 0x0101), /* TDK DF2814 */ | ||
731 | PCMCIA_DEVICE_MANF_CARD(0x0105, 0x100a), /* Xircom CM-56G */ | ||
732 | PCMCIA_DEVICE_MANF_CARD(0x0105, 0x3e0a), /* TDK DF5660 */ | ||
837 | PCMCIA_DEVICE_MANF_CARD(0x0105, 0x410a), | 733 | PCMCIA_DEVICE_MANF_CARD(0x0105, 0x410a), |
734 | PCMCIA_DEVICE_MANF_CARD(0x0107, 0x0002), /* USRobotics 14,400 */ | ||
838 | PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d50), | 735 | PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d50), |
839 | PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d51), | 736 | PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d51), |
840 | PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d52), | 737 | PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d52), |
841 | PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d53), | 738 | PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d53), |
842 | PCMCIA_DEVICE_MANF_CARD(0x010b, 0xd180), | 739 | PCMCIA_DEVICE_MANF_CARD(0x010b, 0xd180), |
740 | PCMCIA_DEVICE_MANF_CARD(0x0115, 0x3330), /* USRobotics/SUN 14,400 */ | ||
741 | PCMCIA_DEVICE_MANF_CARD(0x0124, 0x0100), /* Nokia DTP-2 ver II */ | ||
742 | PCMCIA_DEVICE_MANF_CARD(0x0134, 0x5600), /* LASAT COMMUNICATIONS A/S */ | ||
843 | PCMCIA_DEVICE_MANF_CARD(0x0137, 0x000e), | 743 | PCMCIA_DEVICE_MANF_CARD(0x0137, 0x000e), |
844 | PCMCIA_DEVICE_MANF_CARD(0x0137, 0x001b), | 744 | PCMCIA_DEVICE_MANF_CARD(0x0137, 0x001b), |
845 | PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0025), | 745 | PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0025), |
846 | PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0045), | 746 | PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0045), |
847 | PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0052), | 747 | PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0052), |
748 | PCMCIA_DEVICE_MANF_CARD(0x016c, 0x0006), /* Psion 56K+Fax */ | ||
749 | PCMCIA_DEVICE_MANF_CARD(0x0200, 0x0001), /* MultiMobile */ | ||
848 | PCMCIA_DEVICE_PROD_ID134("ADV", "TECH", "COMpad-32/85", 0x67459937, 0x916d02ba, 0x8fbe92ae), | 750 | PCMCIA_DEVICE_PROD_ID134("ADV", "TECH", "COMpad-32/85", 0x67459937, 0x916d02ba, 0x8fbe92ae), |
849 | PCMCIA_DEVICE_PROD_ID124("GATEWAY2000", "CC3144", "PCMCIA MODEM", 0x506bccae, 0xcb3685f1, 0xbd6c43ef), | 751 | PCMCIA_DEVICE_PROD_ID124("GATEWAY2000", "CC3144", "PCMCIA MODEM", 0x506bccae, 0xcb3685f1, 0xbd6c43ef), |
850 | PCMCIA_DEVICE_PROD_ID14("MEGAHERTZ", "PCMCIA MODEM", 0xf510db04, 0xbd6c43ef), | 752 | PCMCIA_DEVICE_PROD_ID14("MEGAHERTZ", "PCMCIA MODEM", 0xf510db04, 0xbd6c43ef), |
@@ -858,36 +760,44 @@ static struct pcmcia_device_id serial_ids[] = { | |||
858 | PCMCIA_DEVICE_PROD_ID12("COMPAQ", "PCMCIA 33600 FAX/DATA MODEM", 0xa3a3062c, 0x5a00ce95), | 760 | PCMCIA_DEVICE_PROD_ID12("COMPAQ", "PCMCIA 33600 FAX/DATA MODEM", 0xa3a3062c, 0x5a00ce95), |
859 | PCMCIA_DEVICE_PROD_ID12("Computerboards, Inc.", "PCM-COM422", 0xd0b78f51, 0x7e2d49ed), | 761 | PCMCIA_DEVICE_PROD_ID12("Computerboards, Inc.", "PCM-COM422", 0xd0b78f51, 0x7e2d49ed), |
860 | PCMCIA_DEVICE_PROD_ID12("Dr. Neuhaus", "FURY CARD 14K4", 0x76942813, 0x8b96ce65), | 762 | PCMCIA_DEVICE_PROD_ID12("Dr. Neuhaus", "FURY CARD 14K4", 0x76942813, 0x8b96ce65), |
763 | PCMCIA_DEVICE_PROD_ID12("IBM", "ISDN/56K/GSM", 0xb569a6e5, 0xfee5297b), | ||
861 | PCMCIA_DEVICE_PROD_ID12("Intelligent", "ANGIA FAX/MODEM", 0xb496e65e, 0xf31602a6), | 764 | PCMCIA_DEVICE_PROD_ID12("Intelligent", "ANGIA FAX/MODEM", 0xb496e65e, 0xf31602a6), |
862 | PCMCIA_DEVICE_PROD_ID12("Intel", "MODEM 2400+", 0x816cc815, 0x412729fb), | 765 | PCMCIA_DEVICE_PROD_ID12("Intel", "MODEM 2400+", 0x816cc815, 0x412729fb), |
766 | PCMCIA_DEVICE_PROD_ID12("Intertex", "IX34-PCMCIA", 0xf8a097e3, 0x97880447), | ||
863 | PCMCIA_DEVICE_PROD_ID12("IOTech Inc ", "PCMCIA Dual RS-232 Serial Port Card", 0x3bd2d898, 0x92abc92f), | 767 | PCMCIA_DEVICE_PROD_ID12("IOTech Inc ", "PCMCIA Dual RS-232 Serial Port Card", 0x3bd2d898, 0x92abc92f), |
864 | PCMCIA_DEVICE_PROD_ID12("MACRONIX", "FAX/MODEM", 0x668388b3, 0x3f9bdf2f), | 768 | PCMCIA_DEVICE_PROD_ID12("MACRONIX", "FAX/MODEM", 0x668388b3, 0x3f9bdf2f), |
865 | PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT1432LT", 0x5f73be51, 0x0b3e2383), | 769 | PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT1432LT", 0x5f73be51, 0x0b3e2383), |
866 | PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT2834LT", 0x5f73be51, 0x4cd7c09e), | 770 | PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT2834LT", 0x5f73be51, 0x4cd7c09e), |
867 | PCMCIA_DEVICE_PROD_ID12("OEM ", "C288MX ", 0xb572d360, 0xd2385b7a), | 771 | PCMCIA_DEVICE_PROD_ID12("OEM ", "C288MX ", 0xb572d360, 0xd2385b7a), |
772 | PCMCIA_DEVICE_PROD_ID12("Option International", "V34bis GSM/PSTN Data/Fax Modem", 0x9d7cd6f5, 0x5cb8bf41), | ||
868 | PCMCIA_DEVICE_PROD_ID12("PCMCIA ", "C336MX ", 0x99bcafe9, 0xaa25bcab), | 773 | PCMCIA_DEVICE_PROD_ID12("PCMCIA ", "C336MX ", 0x99bcafe9, 0xaa25bcab), |
869 | PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "PCMCIA Dual RS-232 Serial Port Card", 0xc4420b35, 0x92abc92f), | 774 | PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "PCMCIA Dual RS-232 Serial Port Card", 0xc4420b35, 0x92abc92f), |
870 | PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "Dual RS-232 Serial Port PC Card", 0xc4420b35, 0x031a380d), | 775 | PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "Dual RS-232 Serial Port PC Card", 0xc4420b35, 0x031a380d), |
871 | PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "PCMLM28.cis"), | 776 | PCMCIA_DEVICE_PROD_ID12("Telia", "SurfinBird 560P/A+", 0xe2cdd5e, 0xc9314b38), |
872 | PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "PCMLM28.cis"), | 777 | PCMCIA_DEVICE_PROD_ID1("Smart Serial Port", 0x2d8ce292), |
873 | PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "PCMLM28.cis"), | 778 | PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "cis/PCMLM28.cis"), |
874 | PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "PCMLM28.cis"), | 779 | PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "cis/PCMLM28.cis"), |
875 | PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "PCMLM28.cis"), | 780 | PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"), |
876 | PCMCIA_MFC_DEVICE_CIS_PROD_ID12(1, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "DP83903.cis"), | 781 | PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "cis/PCMLM28.cis"), |
877 | PCMCIA_MFC_DEVICE_CIS_PROD_ID4(1, "NSC MF LAN/Modem", 0x58fc6056, "DP83903.cis"), | 782 | PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "cis/PCMLM28.cis"), |
783 | PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "TOSHIBA", "Modem/LAN Card", 0xb4585a1a, 0x53f922f8, "cis/PCMLM28.cis"), | ||
784 | PCMCIA_MFC_DEVICE_CIS_PROD_ID12(1, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "cis/DP83903.cis"), | ||
785 | PCMCIA_MFC_DEVICE_CIS_PROD_ID4(1, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"), | ||
878 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0556, "cis/3CCFEM556.cis"), | 786 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0556, "cis/3CCFEM556.cis"), |
879 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "DP83903.cis"), | 787 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "cis/DP83903.cis"), |
880 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "cis/3CXEM556.cis"), | 788 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "cis/3CXEM556.cis"), |
881 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "cis/3CXEM556.cis"), | 789 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "cis/3CXEM556.cis"), |
882 | PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC850", 0xd85f6206, 0x42a2c018, "SW_8xx_SER.cis"), /* Sierra Wireless AC850 3G Network Adapter R1 */ | 790 | PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC850", 0xd85f6206, 0x42a2c018, "cis/SW_8xx_SER.cis"), /* Sierra Wireless AC850 3G Network Adapter R1 */ |
883 | PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0x0710, "SW_7xx_SER.cis"), /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */ | 791 | PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC860", 0xd85f6206, 0x698f93db, "cis/SW_8xx_SER.cis"), /* Sierra Wireless AC860 3G Network Adapter R1 */ |
884 | PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */ | 792 | PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC710/AC750", 0xd85f6206, 0x761b11e0, "cis/SW_7xx_SER.cis"), /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */ |
885 | PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */ | 793 | PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "cis/SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */ |
886 | PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "MT5634ZLX.cis"), | 794 | PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "cis/SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */ |
887 | PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "COMpad4.cis"), | 795 | PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "cis/MT5634ZLX.cis"), |
888 | PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "COMpad2.cis"), | 796 | PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-2", 0x96913a85, 0x27ab5437, "cis/COMpad2.cis"), |
889 | PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "RS-COM-2P.cis"), | 797 | PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "cis/COMpad4.cis"), |
890 | PCMCIA_DEVICE_CIS_MANF_CARD(0x0013, 0x0000, "GLOBETROTTER.cis"), | 798 | PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "cis/COMpad2.cis"), |
799 | PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "cis/RS-COM-2P.cis"), | ||
800 | PCMCIA_DEVICE_CIS_MANF_CARD(0x0013, 0x0000, "cis/GLOBETROTTER.cis"), | ||
891 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100 1.00.",0x19ca78af,0xf964f42b), | 801 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100 1.00.",0x19ca78af,0xf964f42b), |
892 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100",0x19ca78af,0x71d98e83), | 802 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100",0x19ca78af,0x71d98e83), |
893 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL232 1.00.",0x19ca78af,0x69fb7490), | 803 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL232 1.00.",0x19ca78af,0x69fb7490), |
@@ -921,11 +831,21 @@ static struct pcmcia_device_id serial_ids[] = { | |||
921 | }; | 831 | }; |
922 | MODULE_DEVICE_TABLE(pcmcia, serial_ids); | 832 | MODULE_DEVICE_TABLE(pcmcia, serial_ids); |
923 | 833 | ||
834 | MODULE_FIRMWARE("cis/PCMLM28.cis"); | ||
835 | MODULE_FIRMWARE("cis/DP83903.cis"); | ||
836 | MODULE_FIRMWARE("cis/3CCFEM556.cis"); | ||
837 | MODULE_FIRMWARE("cis/3CXEM556.cis"); | ||
838 | MODULE_FIRMWARE("cis/SW_8xx_SER.cis"); | ||
839 | MODULE_FIRMWARE("cis/SW_7xx_SER.cis"); | ||
840 | MODULE_FIRMWARE("cis/SW_555_SER.cis"); | ||
841 | MODULE_FIRMWARE("cis/MT5634ZLX.cis"); | ||
842 | MODULE_FIRMWARE("cis/COMpad2.cis"); | ||
843 | MODULE_FIRMWARE("cis/COMpad4.cis"); | ||
844 | MODULE_FIRMWARE("cis/RS-COM-2P.cis"); | ||
845 | |||
924 | static struct pcmcia_driver serial_cs_driver = { | 846 | static struct pcmcia_driver serial_cs_driver = { |
925 | .owner = THIS_MODULE, | 847 | .owner = THIS_MODULE, |
926 | .drv = { | 848 | .name = "serial_cs", |
927 | .name = "serial_cs", | ||
928 | }, | ||
929 | .probe = serial_probe, | 849 | .probe = serial_probe, |
930 | .remove = serial_detach, | 850 | .remove = serial_detach, |
931 | .id_table = serial_ids, | 851 | .id_table = serial_ids, |
diff --git a/drivers/serial/serial_ks8695.c b/drivers/serial/serial_ks8695.c index 998e89dc5aaf..b1962025b1aa 100644 --- a/drivers/serial/serial_ks8695.c +++ b/drivers/serial/serial_ks8695.c | |||
@@ -110,7 +110,11 @@ static struct console ks8695_console; | |||
110 | static void ks8695uart_stop_tx(struct uart_port *port) | 110 | static void ks8695uart_stop_tx(struct uart_port *port) |
111 | { | 111 | { |
112 | if (tx_enabled(port)) { | 112 | if (tx_enabled(port)) { |
113 | disable_irq(KS8695_IRQ_UART_TX); | 113 | /* use disable_irq_nosync() and not disable_irq() to avoid self |
114 | * imposed deadlock by not waiting for irq handler to end, | ||
115 | * since this ks8695uart_stop_tx() is called from interrupt context. | ||
116 | */ | ||
117 | disable_irq_nosync(KS8695_IRQ_UART_TX); | ||
114 | tx_enable(port, 0); | 118 | tx_enable(port, 0); |
115 | } | 119 | } |
116 | } | 120 | } |
@@ -150,7 +154,7 @@ static void ks8695uart_disable_ms(struct uart_port *port) | |||
150 | static irqreturn_t ks8695uart_rx_chars(int irq, void *dev_id) | 154 | static irqreturn_t ks8695uart_rx_chars(int irq, void *dev_id) |
151 | { | 155 | { |
152 | struct uart_port *port = dev_id; | 156 | struct uart_port *port = dev_id; |
153 | struct tty_struct *tty = port->info->port.tty; | 157 | struct tty_struct *tty = port->state->port.tty; |
154 | unsigned int status, ch, lsr, flg, max_count = 256; | 158 | unsigned int status, ch, lsr, flg, max_count = 256; |
155 | 159 | ||
156 | status = UART_GET_LSR(port); /* clears pending LSR interrupts */ | 160 | status = UART_GET_LSR(port); /* clears pending LSR interrupts */ |
@@ -206,7 +210,7 @@ ignore_char: | |||
206 | static irqreturn_t ks8695uart_tx_chars(int irq, void *dev_id) | 210 | static irqreturn_t ks8695uart_tx_chars(int irq, void *dev_id) |
207 | { | 211 | { |
208 | struct uart_port *port = dev_id; | 212 | struct uart_port *port = dev_id; |
209 | struct circ_buf *xmit = &port->info->xmit; | 213 | struct circ_buf *xmit = &port->state->xmit; |
210 | unsigned int count; | 214 | unsigned int count; |
211 | 215 | ||
212 | if (port->x_char) { | 216 | if (port->x_char) { |
@@ -262,7 +266,7 @@ static irqreturn_t ks8695uart_modem_status(int irq, void *dev_id) | |||
262 | if (status & URMS_URTERI) | 266 | if (status & URMS_URTERI) |
263 | port->icount.rng++; | 267 | port->icount.rng++; |
264 | 268 | ||
265 | wake_up_interruptible(&port->info->delta_msr_wait); | 269 | wake_up_interruptible(&port->state->port.delta_msr_wait); |
266 | 270 | ||
267 | return IRQ_HANDLED; | 271 | return IRQ_HANDLED; |
268 | } | 272 | } |
@@ -549,7 +553,7 @@ static struct uart_port ks8695uart_ports[SERIAL_KS8695_NR] = { | |||
549 | .mapbase = KS8695_UART_VA, | 553 | .mapbase = KS8695_UART_VA, |
550 | .iotype = SERIAL_IO_MEM, | 554 | .iotype = SERIAL_IO_MEM, |
551 | .irq = KS8695_IRQ_UART_TX, | 555 | .irq = KS8695_IRQ_UART_TX, |
552 | .uartclk = CLOCK_TICK_RATE * 16, | 556 | .uartclk = KS8695_CLOCK_RATE * 16, |
553 | .fifosize = 16, | 557 | .fifosize = 16, |
554 | .ops = &ks8695uart_pops, | 558 | .ops = &ks8695uart_pops, |
555 | .flags = ASYNC_BOOT_AUTOCONF, | 559 | .flags = ASYNC_BOOT_AUTOCONF, |
@@ -646,6 +650,7 @@ static struct console ks8695_console = { | |||
646 | 650 | ||
647 | static int __init ks8695_console_init(void) | 651 | static int __init ks8695_console_init(void) |
648 | { | 652 | { |
653 | add_preferred_console(SERIAL_KS8695_DEVNAME, 0, NULL); | ||
649 | register_console(&ks8695_console); | 654 | register_console(&ks8695_console); |
650 | return 0; | 655 | return 0; |
651 | } | 656 | } |
diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c index a7bf024a8286..ea744707c4d6 100644 --- a/drivers/serial/serial_lh7a40x.c +++ b/drivers/serial/serial_lh7a40x.c | |||
@@ -138,7 +138,7 @@ static void lh7a40xuart_enable_ms (struct uart_port* port) | |||
138 | 138 | ||
139 | static void lh7a40xuart_rx_chars (struct uart_port* port) | 139 | static void lh7a40xuart_rx_chars (struct uart_port* port) |
140 | { | 140 | { |
141 | struct tty_struct* tty = port->info->port.tty; | 141 | struct tty_struct* tty = port->state->port.tty; |
142 | int cbRxMax = 256; /* (Gross) limit on receive */ | 142 | int cbRxMax = 256; /* (Gross) limit on receive */ |
143 | unsigned int data; /* Received data and status */ | 143 | unsigned int data; /* Received data and status */ |
144 | unsigned int flag; | 144 | unsigned int flag; |
@@ -184,7 +184,7 @@ static void lh7a40xuart_rx_chars (struct uart_port* port) | |||
184 | 184 | ||
185 | static void lh7a40xuart_tx_chars (struct uart_port* port) | 185 | static void lh7a40xuart_tx_chars (struct uart_port* port) |
186 | { | 186 | { |
187 | struct circ_buf* xmit = &port->info->xmit; | 187 | struct circ_buf* xmit = &port->state->xmit; |
188 | int cbTxMax = port->fifosize; | 188 | int cbTxMax = port->fifosize; |
189 | 189 | ||
190 | if (port->x_char) { | 190 | if (port->x_char) { |
@@ -241,7 +241,7 @@ static void lh7a40xuart_modem_status (struct uart_port* port) | |||
241 | if (delta & CTS) | 241 | if (delta & CTS) |
242 | uart_handle_cts_change (port, status & CTS); | 242 | uart_handle_cts_change (port, status & CTS); |
243 | 243 | ||
244 | wake_up_interruptible (&port->info->delta_msr_wait); | 244 | wake_up_interruptible (&port->state->port.delta_msr_wait); |
245 | } | 245 | } |
246 | 246 | ||
247 | static irqreturn_t lh7a40xuart_int (int irq, void* dev_id) | 247 | static irqreturn_t lh7a40xuart_int (int irq, void* dev_id) |
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c index 7313c2edcb83..c50e9fbbf743 100644 --- a/drivers/serial/serial_txx9.c +++ b/drivers/serial/serial_txx9.c | |||
@@ -221,21 +221,26 @@ sio_quot_set(struct uart_txx9_port *up, int quot) | |||
221 | sio_out(up, TXX9_SIBGR, 0xff | TXX9_SIBGR_BCLK_T6); | 221 | sio_out(up, TXX9_SIBGR, 0xff | TXX9_SIBGR_BCLK_T6); |
222 | } | 222 | } |
223 | 223 | ||
224 | static struct uart_txx9_port *to_uart_txx9_port(struct uart_port *port) | ||
225 | { | ||
226 | return container_of(port, struct uart_txx9_port, port); | ||
227 | } | ||
228 | |||
224 | static void serial_txx9_stop_tx(struct uart_port *port) | 229 | static void serial_txx9_stop_tx(struct uart_port *port) |
225 | { | 230 | { |
226 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 231 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
227 | sio_mask(up, TXX9_SIDICR, TXX9_SIDICR_TIE); | 232 | sio_mask(up, TXX9_SIDICR, TXX9_SIDICR_TIE); |
228 | } | 233 | } |
229 | 234 | ||
230 | static void serial_txx9_start_tx(struct uart_port *port) | 235 | static void serial_txx9_start_tx(struct uart_port *port) |
231 | { | 236 | { |
232 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 237 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
233 | sio_set(up, TXX9_SIDICR, TXX9_SIDICR_TIE); | 238 | sio_set(up, TXX9_SIDICR, TXX9_SIDICR_TIE); |
234 | } | 239 | } |
235 | 240 | ||
236 | static void serial_txx9_stop_rx(struct uart_port *port) | 241 | static void serial_txx9_stop_rx(struct uart_port *port) |
237 | { | 242 | { |
238 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 243 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
239 | up->port.read_status_mask &= ~TXX9_SIDISR_RDIS; | 244 | up->port.read_status_mask &= ~TXX9_SIDISR_RDIS; |
240 | } | 245 | } |
241 | 246 | ||
@@ -246,7 +251,7 @@ static void serial_txx9_enable_ms(struct uart_port *port) | |||
246 | 251 | ||
247 | static void serial_txx9_initialize(struct uart_port *port) | 252 | static void serial_txx9_initialize(struct uart_port *port) |
248 | { | 253 | { |
249 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 254 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
250 | unsigned int tmout = 10000; | 255 | unsigned int tmout = 10000; |
251 | 256 | ||
252 | sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST); | 257 | sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST); |
@@ -272,7 +277,7 @@ static void serial_txx9_initialize(struct uart_port *port) | |||
272 | static inline void | 277 | static inline void |
273 | receive_chars(struct uart_txx9_port *up, unsigned int *status) | 278 | receive_chars(struct uart_txx9_port *up, unsigned int *status) |
274 | { | 279 | { |
275 | struct tty_struct *tty = up->port.info->port.tty; | 280 | struct tty_struct *tty = up->port.state->port.tty; |
276 | unsigned char ch; | 281 | unsigned char ch; |
277 | unsigned int disr = *status; | 282 | unsigned int disr = *status; |
278 | int max_count = 256; | 283 | int max_count = 256; |
@@ -348,7 +353,7 @@ receive_chars(struct uart_txx9_port *up, unsigned int *status) | |||
348 | 353 | ||
349 | static inline void transmit_chars(struct uart_txx9_port *up) | 354 | static inline void transmit_chars(struct uart_txx9_port *up) |
350 | { | 355 | { |
351 | struct circ_buf *xmit = &up->port.info->xmit; | 356 | struct circ_buf *xmit = &up->port.state->xmit; |
352 | int count; | 357 | int count; |
353 | 358 | ||
354 | if (up->port.x_char) { | 359 | if (up->port.x_char) { |
@@ -414,7 +419,7 @@ static irqreturn_t serial_txx9_interrupt(int irq, void *dev_id) | |||
414 | 419 | ||
415 | static unsigned int serial_txx9_tx_empty(struct uart_port *port) | 420 | static unsigned int serial_txx9_tx_empty(struct uart_port *port) |
416 | { | 421 | { |
417 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 422 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
418 | unsigned long flags; | 423 | unsigned long flags; |
419 | unsigned int ret; | 424 | unsigned int ret; |
420 | 425 | ||
@@ -427,7 +432,7 @@ static unsigned int serial_txx9_tx_empty(struct uart_port *port) | |||
427 | 432 | ||
428 | static unsigned int serial_txx9_get_mctrl(struct uart_port *port) | 433 | static unsigned int serial_txx9_get_mctrl(struct uart_port *port) |
429 | { | 434 | { |
430 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 435 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
431 | unsigned int ret; | 436 | unsigned int ret; |
432 | 437 | ||
433 | /* no modem control lines */ | 438 | /* no modem control lines */ |
@@ -440,7 +445,7 @@ static unsigned int serial_txx9_get_mctrl(struct uart_port *port) | |||
440 | 445 | ||
441 | static void serial_txx9_set_mctrl(struct uart_port *port, unsigned int mctrl) | 446 | static void serial_txx9_set_mctrl(struct uart_port *port, unsigned int mctrl) |
442 | { | 447 | { |
443 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 448 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
444 | 449 | ||
445 | if (mctrl & TIOCM_RTS) | 450 | if (mctrl & TIOCM_RTS) |
446 | sio_mask(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSSC); | 451 | sio_mask(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSSC); |
@@ -450,7 +455,7 @@ static void serial_txx9_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
450 | 455 | ||
451 | static void serial_txx9_break_ctl(struct uart_port *port, int break_state) | 456 | static void serial_txx9_break_ctl(struct uart_port *port, int break_state) |
452 | { | 457 | { |
453 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 458 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
454 | unsigned long flags; | 459 | unsigned long flags; |
455 | 460 | ||
456 | spin_lock_irqsave(&up->port.lock, flags); | 461 | spin_lock_irqsave(&up->port.lock, flags); |
@@ -461,9 +466,97 @@ static void serial_txx9_break_ctl(struct uart_port *port, int break_state) | |||
461 | spin_unlock_irqrestore(&up->port.lock, flags); | 466 | spin_unlock_irqrestore(&up->port.lock, flags); |
462 | } | 467 | } |
463 | 468 | ||
469 | #if defined(CONFIG_SERIAL_TXX9_CONSOLE) || (CONFIG_CONSOLE_POLL) | ||
470 | /* | ||
471 | * Wait for transmitter & holding register to empty | ||
472 | */ | ||
473 | static void wait_for_xmitr(struct uart_txx9_port *up) | ||
474 | { | ||
475 | unsigned int tmout = 10000; | ||
476 | |||
477 | /* Wait up to 10ms for the character(s) to be sent. */ | ||
478 | while (--tmout && | ||
479 | !(sio_in(up, TXX9_SICISR) & TXX9_SICISR_TXALS)) | ||
480 | udelay(1); | ||
481 | |||
482 | /* Wait up to 1s for flow control if necessary */ | ||
483 | if (up->port.flags & UPF_CONS_FLOW) { | ||
484 | tmout = 1000000; | ||
485 | while (--tmout && | ||
486 | (sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS)) | ||
487 | udelay(1); | ||
488 | } | ||
489 | } | ||
490 | #endif | ||
491 | |||
492 | #ifdef CONFIG_CONSOLE_POLL | ||
493 | /* | ||
494 | * Console polling routines for writing and reading from the uart while | ||
495 | * in an interrupt or debug context. | ||
496 | */ | ||
497 | |||
498 | static int serial_txx9_get_poll_char(struct uart_port *port) | ||
499 | { | ||
500 | unsigned int ier; | ||
501 | unsigned char c; | ||
502 | struct uart_txx9_port *up = to_uart_txx9_port(port); | ||
503 | |||
504 | /* | ||
505 | * First save the IER then disable the interrupts | ||
506 | */ | ||
507 | ier = sio_in(up, TXX9_SIDICR); | ||
508 | sio_out(up, TXX9_SIDICR, 0); | ||
509 | |||
510 | while (sio_in(up, TXX9_SIDISR) & TXX9_SIDISR_UVALID) | ||
511 | ; | ||
512 | |||
513 | c = sio_in(up, TXX9_SIRFIFO); | ||
514 | |||
515 | /* | ||
516 | * Finally, clear RX interrupt status | ||
517 | * and restore the IER | ||
518 | */ | ||
519 | sio_mask(up, TXX9_SIDISR, TXX9_SIDISR_RDIS); | ||
520 | sio_out(up, TXX9_SIDICR, ier); | ||
521 | return c; | ||
522 | } | ||
523 | |||
524 | |||
525 | static void serial_txx9_put_poll_char(struct uart_port *port, unsigned char c) | ||
526 | { | ||
527 | unsigned int ier; | ||
528 | struct uart_txx9_port *up = to_uart_txx9_port(port); | ||
529 | |||
530 | /* | ||
531 | * First save the IER then disable the interrupts | ||
532 | */ | ||
533 | ier = sio_in(up, TXX9_SIDICR); | ||
534 | sio_out(up, TXX9_SIDICR, 0); | ||
535 | |||
536 | wait_for_xmitr(up); | ||
537 | /* | ||
538 | * Send the character out. | ||
539 | * If a LF, also do CR... | ||
540 | */ | ||
541 | sio_out(up, TXX9_SITFIFO, c); | ||
542 | if (c == 10) { | ||
543 | wait_for_xmitr(up); | ||
544 | sio_out(up, TXX9_SITFIFO, 13); | ||
545 | } | ||
546 | |||
547 | /* | ||
548 | * Finally, wait for transmitter to become empty | ||
549 | * and restore the IER | ||
550 | */ | ||
551 | wait_for_xmitr(up); | ||
552 | sio_out(up, TXX9_SIDICR, ier); | ||
553 | } | ||
554 | |||
555 | #endif /* CONFIG_CONSOLE_POLL */ | ||
556 | |||
464 | static int serial_txx9_startup(struct uart_port *port) | 557 | static int serial_txx9_startup(struct uart_port *port) |
465 | { | 558 | { |
466 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 559 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
467 | unsigned long flags; | 560 | unsigned long flags; |
468 | int retval; | 561 | int retval; |
469 | 562 | ||
@@ -508,7 +601,7 @@ static int serial_txx9_startup(struct uart_port *port) | |||
508 | 601 | ||
509 | static void serial_txx9_shutdown(struct uart_port *port) | 602 | static void serial_txx9_shutdown(struct uart_port *port) |
510 | { | 603 | { |
511 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 604 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
512 | unsigned long flags; | 605 | unsigned long flags; |
513 | 606 | ||
514 | /* | 607 | /* |
@@ -548,7 +641,7 @@ static void | |||
548 | serial_txx9_set_termios(struct uart_port *port, struct ktermios *termios, | 641 | serial_txx9_set_termios(struct uart_port *port, struct ktermios *termios, |
549 | struct ktermios *old) | 642 | struct ktermios *old) |
550 | { | 643 | { |
551 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 644 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
552 | unsigned int cval, fcr = 0; | 645 | unsigned int cval, fcr = 0; |
553 | unsigned long flags; | 646 | unsigned long flags; |
554 | unsigned int baud, quot; | 647 | unsigned int baud, quot; |
@@ -726,19 +819,19 @@ static void serial_txx9_release_resource(struct uart_txx9_port *up) | |||
726 | 819 | ||
727 | static void serial_txx9_release_port(struct uart_port *port) | 820 | static void serial_txx9_release_port(struct uart_port *port) |
728 | { | 821 | { |
729 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 822 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
730 | serial_txx9_release_resource(up); | 823 | serial_txx9_release_resource(up); |
731 | } | 824 | } |
732 | 825 | ||
733 | static int serial_txx9_request_port(struct uart_port *port) | 826 | static int serial_txx9_request_port(struct uart_port *port) |
734 | { | 827 | { |
735 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 828 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
736 | return serial_txx9_request_resource(up); | 829 | return serial_txx9_request_resource(up); |
737 | } | 830 | } |
738 | 831 | ||
739 | static void serial_txx9_config_port(struct uart_port *port, int uflags) | 832 | static void serial_txx9_config_port(struct uart_port *port, int uflags) |
740 | { | 833 | { |
741 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 834 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
742 | int ret; | 835 | int ret; |
743 | 836 | ||
744 | /* | 837 | /* |
@@ -781,6 +874,10 @@ static struct uart_ops serial_txx9_pops = { | |||
781 | .release_port = serial_txx9_release_port, | 874 | .release_port = serial_txx9_release_port, |
782 | .request_port = serial_txx9_request_port, | 875 | .request_port = serial_txx9_request_port, |
783 | .config_port = serial_txx9_config_port, | 876 | .config_port = serial_txx9_config_port, |
877 | #ifdef CONFIG_CONSOLE_POLL | ||
878 | .poll_get_char = serial_txx9_get_poll_char, | ||
879 | .poll_put_char = serial_txx9_put_poll_char, | ||
880 | #endif | ||
784 | }; | 881 | }; |
785 | 882 | ||
786 | static struct uart_txx9_port serial_txx9_ports[UART_NR]; | 883 | static struct uart_txx9_port serial_txx9_ports[UART_NR]; |
@@ -803,30 +900,9 @@ static void __init serial_txx9_register_ports(struct uart_driver *drv, | |||
803 | 900 | ||
804 | #ifdef CONFIG_SERIAL_TXX9_CONSOLE | 901 | #ifdef CONFIG_SERIAL_TXX9_CONSOLE |
805 | 902 | ||
806 | /* | ||
807 | * Wait for transmitter & holding register to empty | ||
808 | */ | ||
809 | static inline void wait_for_xmitr(struct uart_txx9_port *up) | ||
810 | { | ||
811 | unsigned int tmout = 10000; | ||
812 | |||
813 | /* Wait up to 10ms for the character(s) to be sent. */ | ||
814 | while (--tmout && | ||
815 | !(sio_in(up, TXX9_SICISR) & TXX9_SICISR_TXALS)) | ||
816 | udelay(1); | ||
817 | |||
818 | /* Wait up to 1s for flow control if necessary */ | ||
819 | if (up->port.flags & UPF_CONS_FLOW) { | ||
820 | tmout = 1000000; | ||
821 | while (--tmout && | ||
822 | (sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS)) | ||
823 | udelay(1); | ||
824 | } | ||
825 | } | ||
826 | |||
827 | static void serial_txx9_console_putchar(struct uart_port *port, int ch) | 903 | static void serial_txx9_console_putchar(struct uart_port *port, int ch) |
828 | { | 904 | { |
829 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 905 | struct uart_txx9_port *up = to_uart_txx9_port(port); |
830 | 906 | ||
831 | wait_for_xmitr(up); | 907 | wait_for_xmitr(up); |
832 | sio_out(up, TXX9_SITFIFO, ch); | 908 | sio_out(up, TXX9_SITFIFO, ch); |
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 403b01b382e2..251c08c55ae0 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SuperH on-chip serial module support. (SCI with no FIFO / with FIFO) | 4 | * SuperH on-chip serial module support. (SCI with no FIFO / with FIFO) |
5 | * | 5 | * |
6 | * Copyright (C) 2002 - 2008 Paul Mundt | 6 | * Copyright (C) 2002 - 2011 Paul Mundt |
7 | * Modified to support SH7720 SCIF. Markus Brunner, Mark Jonas (Jul 2007). | 7 | * Modified to support SH7720 SCIF. Markus Brunner, Mark Jonas (Jul 2007). |
8 | * | 8 | * |
9 | * based off of the old drivers/char/sh-sci.c by: | 9 | * based off of the old drivers/char/sh-sci.c by: |
@@ -48,9 +48,11 @@ | |||
48 | #include <linux/ctype.h> | 48 | #include <linux/ctype.h> |
49 | #include <linux/err.h> | 49 | #include <linux/err.h> |
50 | #include <linux/list.h> | 50 | #include <linux/list.h> |
51 | #include <linux/dmaengine.h> | ||
52 | #include <linux/scatterlist.h> | ||
53 | #include <linux/slab.h> | ||
51 | 54 | ||
52 | #ifdef CONFIG_SUPERH | 55 | #ifdef CONFIG_SUPERH |
53 | #include <asm/clock.h> | ||
54 | #include <asm/sh_bios.h> | 56 | #include <asm/sh_bios.h> |
55 | #endif | 57 | #endif |
56 | 58 | ||
@@ -85,22 +87,42 @@ struct sci_port { | |||
85 | /* SCBRR calculation algo */ | 87 | /* SCBRR calculation algo */ |
86 | unsigned int scbrr_algo_id; | 88 | unsigned int scbrr_algo_id; |
87 | 89 | ||
88 | #ifdef CONFIG_HAVE_CLK | ||
89 | /* Interface clock */ | 90 | /* Interface clock */ |
90 | struct clk *iclk; | 91 | struct clk *iclk; |
91 | /* Data clock */ | 92 | /* Function clock */ |
92 | struct clk *dclk; | 93 | struct clk *fclk; |
93 | #endif | 94 | |
94 | struct list_head node; | 95 | struct list_head node; |
96 | |||
97 | struct dma_chan *chan_tx; | ||
98 | struct dma_chan *chan_rx; | ||
99 | |||
100 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | ||
101 | struct device *dma_dev; | ||
102 | unsigned int slave_tx; | ||
103 | unsigned int slave_rx; | ||
104 | struct dma_async_tx_descriptor *desc_tx; | ||
105 | struct dma_async_tx_descriptor *desc_rx[2]; | ||
106 | dma_cookie_t cookie_tx; | ||
107 | dma_cookie_t cookie_rx[2]; | ||
108 | dma_cookie_t active_rx; | ||
109 | struct scatterlist sg_tx; | ||
110 | unsigned int sg_len_tx; | ||
111 | struct scatterlist sg_rx[2]; | ||
112 | size_t buf_len_rx; | ||
113 | struct sh_dmae_slave param_tx; | ||
114 | struct sh_dmae_slave param_rx; | ||
115 | struct work_struct work_tx; | ||
116 | struct work_struct work_rx; | ||
117 | struct timer_list rx_timer; | ||
118 | unsigned int rx_timeout; | ||
119 | #endif | ||
95 | }; | 120 | }; |
96 | 121 | ||
97 | struct sh_sci_priv { | 122 | struct sh_sci_priv { |
98 | spinlock_t lock; | 123 | spinlock_t lock; |
99 | struct list_head ports; | 124 | struct list_head ports; |
100 | |||
101 | #ifdef CONFIG_HAVE_CLK | ||
102 | struct notifier_block clk_nb; | 125 | struct notifier_block clk_nb; |
103 | #endif | ||
104 | }; | 126 | }; |
105 | 127 | ||
106 | /* Function prototypes */ | 128 | /* Function prototypes */ |
@@ -137,7 +159,11 @@ static int sci_poll_get_char(struct uart_port *port) | |||
137 | handle_error(port); | 159 | handle_error(port); |
138 | continue; | 160 | continue; |
139 | } | 161 | } |
140 | } while (!(status & SCxSR_RDxF(port))); | 162 | break; |
163 | } while (1); | ||
164 | |||
165 | if (!(status & SCxSR_RDxF(port))) | ||
166 | return NO_POLL_CHAR; | ||
141 | 167 | ||
142 | c = sci_in(port, SCxRDR); | 168 | c = sci_in(port, SCxRDR); |
143 | 169 | ||
@@ -162,32 +188,6 @@ static void sci_poll_put_char(struct uart_port *port, unsigned char c) | |||
162 | } | 188 | } |
163 | #endif /* CONFIG_CONSOLE_POLL || CONFIG_SERIAL_SH_SCI_CONSOLE */ | 189 | #endif /* CONFIG_CONSOLE_POLL || CONFIG_SERIAL_SH_SCI_CONSOLE */ |
164 | 190 | ||
165 | #if defined(__H8300S__) | ||
166 | enum { sci_disable, sci_enable }; | ||
167 | |||
168 | static void h8300_sci_config(struct uart_port *port, unsigned int ctrl) | ||
169 | { | ||
170 | volatile unsigned char *mstpcrl = (volatile unsigned char *)MSTPCRL; | ||
171 | int ch = (port->mapbase - SMR0) >> 3; | ||
172 | unsigned char mask = 1 << (ch+1); | ||
173 | |||
174 | if (ctrl == sci_disable) | ||
175 | *mstpcrl |= mask; | ||
176 | else | ||
177 | *mstpcrl &= ~mask; | ||
178 | } | ||
179 | |||
180 | static void h8300_sci_enable(struct uart_port *port) | ||
181 | { | ||
182 | h8300_sci_config(port, sci_enable); | ||
183 | } | ||
184 | |||
185 | static void h8300_sci_disable(struct uart_port *port) | ||
186 | { | ||
187 | h8300_sci_config(port, sci_disable); | ||
188 | } | ||
189 | #endif | ||
190 | |||
191 | #if defined(__H8300H__) || defined(__H8300S__) | 191 | #if defined(__H8300H__) || defined(__H8300S__) |
192 | static void sci_init_pins(struct uart_port *port, unsigned int cflag) | 192 | static void sci_init_pins(struct uart_port *port, unsigned int cflag) |
193 | { | 193 | { |
@@ -259,9 +259,9 @@ static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) | |||
259 | Set SCP6MD1,0 = {01} (output) */ | 259 | Set SCP6MD1,0 = {01} (output) */ |
260 | __raw_writew((data & 0x0fcf) | 0x1000, SCPCR); | 260 | __raw_writew((data & 0x0fcf) | 0x1000, SCPCR); |
261 | 261 | ||
262 | data = ctrl_inb(SCPDR); | 262 | data = __raw_readb(SCPDR); |
263 | /* Set /RTS2 (bit6) = 0 */ | 263 | /* Set /RTS2 (bit6) = 0 */ |
264 | ctrl_outb(data & 0xbf, SCPDR); | 264 | __raw_writeb(data & 0xbf, SCPDR); |
265 | } | 265 | } |
266 | } | 266 | } |
267 | #elif defined(CONFIG_CPU_SUBTYPE_SH7722) | 267 | #elif defined(CONFIG_CPU_SUBTYPE_SH7722) |
@@ -278,7 +278,8 @@ static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) | |||
278 | __raw_writew(data, PSCR); | 278 | __raw_writew(data, PSCR); |
279 | } | 279 | } |
280 | } | 280 | } |
281 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \ | 281 | #elif defined(CONFIG_CPU_SUBTYPE_SH7757) || \ |
282 | defined(CONFIG_CPU_SUBTYPE_SH7763) || \ | ||
282 | defined(CONFIG_CPU_SUBTYPE_SH7780) || \ | 283 | defined(CONFIG_CPU_SUBTYPE_SH7780) || \ |
283 | defined(CONFIG_CPU_SUBTYPE_SH7785) || \ | 284 | defined(CONFIG_CPU_SUBTYPE_SH7785) || \ |
284 | defined(CONFIG_CPU_SUBTYPE_SH7786) || \ | 285 | defined(CONFIG_CPU_SUBTYPE_SH7786) || \ |
@@ -305,29 +306,44 @@ static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) | |||
305 | defined(CONFIG_CPU_SUBTYPE_SH7780) || \ | 306 | defined(CONFIG_CPU_SUBTYPE_SH7780) || \ |
306 | defined(CONFIG_CPU_SUBTYPE_SH7785) || \ | 307 | defined(CONFIG_CPU_SUBTYPE_SH7785) || \ |
307 | defined(CONFIG_CPU_SUBTYPE_SH7786) | 308 | defined(CONFIG_CPU_SUBTYPE_SH7786) |
308 | static inline int scif_txroom(struct uart_port *port) | 309 | static int scif_txfill(struct uart_port *port) |
310 | { | ||
311 | return sci_in(port, SCTFDR) & 0xff; | ||
312 | } | ||
313 | |||
314 | static int scif_txroom(struct uart_port *port) | ||
309 | { | 315 | { |
310 | return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0xff); | 316 | return SCIF_TXROOM_MAX - scif_txfill(port); |
311 | } | 317 | } |
312 | 318 | ||
313 | static inline int scif_rxroom(struct uart_port *port) | 319 | static int scif_rxfill(struct uart_port *port) |
314 | { | 320 | { |
315 | return sci_in(port, SCRFDR) & 0xff; | 321 | return sci_in(port, SCRFDR) & 0xff; |
316 | } | 322 | } |
317 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) | 323 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) |
318 | static inline int scif_txroom(struct uart_port *port) | 324 | static int scif_txfill(struct uart_port *port) |
319 | { | 325 | { |
320 | if ((port->mapbase == 0xffe00000) || | 326 | if (port->mapbase == 0xffe00000 || |
321 | (port->mapbase == 0xffe08000)) { | 327 | port->mapbase == 0xffe08000) |
322 | /* SCIF0/1*/ | 328 | /* SCIF0/1*/ |
323 | return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0xff); | 329 | return sci_in(port, SCTFDR) & 0xff; |
324 | } else { | 330 | else |
325 | /* SCIF2 */ | 331 | /* SCIF2 */ |
326 | return SCIF2_TXROOM_MAX - (sci_in(port, SCFDR) >> 8); | 332 | return sci_in(port, SCFDR) >> 8; |
327 | } | ||
328 | } | 333 | } |
329 | 334 | ||
330 | static inline int scif_rxroom(struct uart_port *port) | 335 | static int scif_txroom(struct uart_port *port) |
336 | { | ||
337 | if (port->mapbase == 0xffe00000 || | ||
338 | port->mapbase == 0xffe08000) | ||
339 | /* SCIF0/1*/ | ||
340 | return SCIF_TXROOM_MAX - scif_txfill(port); | ||
341 | else | ||
342 | /* SCIF2 */ | ||
343 | return SCIF2_TXROOM_MAX - scif_txfill(port); | ||
344 | } | ||
345 | |||
346 | static int scif_rxfill(struct uart_port *port) | ||
331 | { | 347 | { |
332 | if ((port->mapbase == 0xffe00000) || | 348 | if ((port->mapbase == 0xffe00000) || |
333 | (port->mapbase == 0xffe08000)) { | 349 | (port->mapbase == 0xffe08000)) { |
@@ -338,24 +354,55 @@ static inline int scif_rxroom(struct uart_port *port) | |||
338 | return sci_in(port, SCFDR) & SCIF2_RFDC_MASK; | 354 | return sci_in(port, SCFDR) & SCIF2_RFDC_MASK; |
339 | } | 355 | } |
340 | } | 356 | } |
357 | #elif defined(CONFIG_ARCH_SH7372) | ||
358 | static int scif_txfill(struct uart_port *port) | ||
359 | { | ||
360 | if (port->type == PORT_SCIFA) | ||
361 | return sci_in(port, SCFDR) >> 8; | ||
362 | else | ||
363 | return sci_in(port, SCTFDR); | ||
364 | } | ||
365 | |||
366 | static int scif_txroom(struct uart_port *port) | ||
367 | { | ||
368 | return port->fifosize - scif_txfill(port); | ||
369 | } | ||
370 | |||
371 | static int scif_rxfill(struct uart_port *port) | ||
372 | { | ||
373 | if (port->type == PORT_SCIFA) | ||
374 | return sci_in(port, SCFDR) & SCIF_RFDC_MASK; | ||
375 | else | ||
376 | return sci_in(port, SCRFDR); | ||
377 | } | ||
341 | #else | 378 | #else |
342 | static inline int scif_txroom(struct uart_port *port) | 379 | static int scif_txfill(struct uart_port *port) |
380 | { | ||
381 | return sci_in(port, SCFDR) >> 8; | ||
382 | } | ||
383 | |||
384 | static int scif_txroom(struct uart_port *port) | ||
343 | { | 385 | { |
344 | return SCIF_TXROOM_MAX - (sci_in(port, SCFDR) >> 8); | 386 | return SCIF_TXROOM_MAX - scif_txfill(port); |
345 | } | 387 | } |
346 | 388 | ||
347 | static inline int scif_rxroom(struct uart_port *port) | 389 | static int scif_rxfill(struct uart_port *port) |
348 | { | 390 | { |
349 | return sci_in(port, SCFDR) & SCIF_RFDC_MASK; | 391 | return sci_in(port, SCFDR) & SCIF_RFDC_MASK; |
350 | } | 392 | } |
351 | #endif | 393 | #endif |
352 | 394 | ||
353 | static inline int sci_txroom(struct uart_port *port) | 395 | static int sci_txfill(struct uart_port *port) |
354 | { | 396 | { |
355 | return (sci_in(port, SCxSR) & SCI_TDRE) != 0; | 397 | return !(sci_in(port, SCxSR) & SCI_TDRE); |
356 | } | 398 | } |
357 | 399 | ||
358 | static inline int sci_rxroom(struct uart_port *port) | 400 | static int sci_txroom(struct uart_port *port) |
401 | { | ||
402 | return !sci_txfill(port); | ||
403 | } | ||
404 | |||
405 | static int sci_rxfill(struct uart_port *port) | ||
359 | { | 406 | { |
360 | return (sci_in(port, SCxSR) & SCxSR_RDxF(port)) != 0; | 407 | return (sci_in(port, SCxSR) & SCxSR_RDxF(port)) != 0; |
361 | } | 408 | } |
@@ -366,7 +413,7 @@ static inline int sci_rxroom(struct uart_port *port) | |||
366 | 413 | ||
367 | static void sci_transmit_chars(struct uart_port *port) | 414 | static void sci_transmit_chars(struct uart_port *port) |
368 | { | 415 | { |
369 | struct circ_buf *xmit = &port->info->xmit; | 416 | struct circ_buf *xmit = &port->state->xmit; |
370 | unsigned int stopped = uart_tx_stopped(port); | 417 | unsigned int stopped = uart_tx_stopped(port); |
371 | unsigned short status; | 418 | unsigned short status; |
372 | unsigned short ctrl; | 419 | unsigned short ctrl; |
@@ -431,7 +478,7 @@ static void sci_transmit_chars(struct uart_port *port) | |||
431 | static inline void sci_receive_chars(struct uart_port *port) | 478 | static inline void sci_receive_chars(struct uart_port *port) |
432 | { | 479 | { |
433 | struct sci_port *sci_port = to_sci_port(port); | 480 | struct sci_port *sci_port = to_sci_port(port); |
434 | struct tty_struct *tty = port->info->port.tty; | 481 | struct tty_struct *tty = port->state->port.tty; |
435 | int i, count, copied = 0; | 482 | int i, count, copied = 0; |
436 | unsigned short status; | 483 | unsigned short status; |
437 | unsigned char flag; | 484 | unsigned char flag; |
@@ -442,9 +489,9 @@ static inline void sci_receive_chars(struct uart_port *port) | |||
442 | 489 | ||
443 | while (1) { | 490 | while (1) { |
444 | if (port->type == PORT_SCI) | 491 | if (port->type == PORT_SCI) |
445 | count = sci_rxroom(port); | 492 | count = sci_rxfill(port); |
446 | else | 493 | else |
447 | count = scif_rxroom(port); | 494 | count = scif_rxfill(port); |
448 | 495 | ||
449 | /* Don't copy more bytes than there is room for in the buffer */ | 496 | /* Don't copy more bytes than there is room for in the buffer */ |
450 | count = tty_buffer_request_room(tty, count); | 497 | count = tty_buffer_request_room(tty, count); |
@@ -489,10 +536,10 @@ static inline void sci_receive_chars(struct uart_port *port) | |||
489 | } | 536 | } |
490 | 537 | ||
491 | /* Store data and status */ | 538 | /* Store data and status */ |
492 | if (status&SCxSR_FER(port)) { | 539 | if (status & SCxSR_FER(port)) { |
493 | flag = TTY_FRAME; | 540 | flag = TTY_FRAME; |
494 | dev_notice(port->dev, "frame error\n"); | 541 | dev_notice(port->dev, "frame error\n"); |
495 | } else if (status&SCxSR_PER(port)) { | 542 | } else if (status & SCxSR_PER(port)) { |
496 | flag = TTY_PARITY; | 543 | flag = TTY_PARITY; |
497 | dev_notice(port->dev, "parity error\n"); | 544 | dev_notice(port->dev, "parity error\n"); |
498 | } else | 545 | } else |
@@ -551,7 +598,7 @@ static inline int sci_handle_errors(struct uart_port *port) | |||
551 | { | 598 | { |
552 | int copied = 0; | 599 | int copied = 0; |
553 | unsigned short status = sci_in(port, SCxSR); | 600 | unsigned short status = sci_in(port, SCxSR); |
554 | struct tty_struct *tty = port->info->port.tty; | 601 | struct tty_struct *tty = port->state->port.tty; |
555 | 602 | ||
556 | if (status & SCxSR_ORER(port)) { | 603 | if (status & SCxSR_ORER(port)) { |
557 | /* overrun error */ | 604 | /* overrun error */ |
@@ -605,7 +652,7 @@ static inline int sci_handle_errors(struct uart_port *port) | |||
605 | 652 | ||
606 | static inline int sci_handle_fifo_overrun(struct uart_port *port) | 653 | static inline int sci_handle_fifo_overrun(struct uart_port *port) |
607 | { | 654 | { |
608 | struct tty_struct *tty = port->info->port.tty; | 655 | struct tty_struct *tty = port->state->port.tty; |
609 | int copied = 0; | 656 | int copied = 0; |
610 | 657 | ||
611 | if (port->type != PORT_SCIF) | 658 | if (port->type != PORT_SCIF) |
@@ -628,7 +675,7 @@ static inline int sci_handle_breaks(struct uart_port *port) | |||
628 | { | 675 | { |
629 | int copied = 0; | 676 | int copied = 0; |
630 | unsigned short status = sci_in(port, SCxSR); | 677 | unsigned short status = sci_in(port, SCxSR); |
631 | struct tty_struct *tty = port->info->port.tty; | 678 | struct tty_struct *tty = port->state->port.tty; |
632 | struct sci_port *s = to_sci_port(port); | 679 | struct sci_port *s = to_sci_port(port); |
633 | 680 | ||
634 | if (uart_handle_break(port)) | 681 | if (uart_handle_break(port)) |
@@ -654,13 +701,39 @@ static inline int sci_handle_breaks(struct uart_port *port) | |||
654 | return copied; | 701 | return copied; |
655 | } | 702 | } |
656 | 703 | ||
657 | static irqreturn_t sci_rx_interrupt(int irq, void *port) | 704 | static irqreturn_t sci_rx_interrupt(int irq, void *ptr) |
658 | { | 705 | { |
706 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | ||
707 | struct uart_port *port = ptr; | ||
708 | struct sci_port *s = to_sci_port(port); | ||
709 | |||
710 | if (s->chan_rx) { | ||
711 | u16 scr = sci_in(port, SCSCR); | ||
712 | u16 ssr = sci_in(port, SCxSR); | ||
713 | |||
714 | /* Disable future Rx interrupts */ | ||
715 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { | ||
716 | disable_irq_nosync(irq); | ||
717 | scr |= 0x4000; | ||
718 | } else { | ||
719 | scr &= ~SCSCR_RIE; | ||
720 | } | ||
721 | sci_out(port, SCSCR, scr); | ||
722 | /* Clear current interrupt */ | ||
723 | sci_out(port, SCxSR, ssr & ~(1 | SCxSR_RDxF(port))); | ||
724 | dev_dbg(port->dev, "Rx IRQ %lu: setup t-out in %u jiffies\n", | ||
725 | jiffies, s->rx_timeout); | ||
726 | mod_timer(&s->rx_timer, jiffies + s->rx_timeout); | ||
727 | |||
728 | return IRQ_HANDLED; | ||
729 | } | ||
730 | #endif | ||
731 | |||
659 | /* I think sci_receive_chars has to be called irrespective | 732 | /* I think sci_receive_chars has to be called irrespective |
660 | * of whether the I_IXOFF is set, otherwise, how is the interrupt | 733 | * of whether the I_IXOFF is set, otherwise, how is the interrupt |
661 | * to be disabled? | 734 | * to be disabled? |
662 | */ | 735 | */ |
663 | sci_receive_chars(port); | 736 | sci_receive_chars(ptr); |
664 | 737 | ||
665 | return IRQ_HANDLED; | 738 | return IRQ_HANDLED; |
666 | } | 739 | } |
@@ -668,10 +741,11 @@ static irqreturn_t sci_rx_interrupt(int irq, void *port) | |||
668 | static irqreturn_t sci_tx_interrupt(int irq, void *ptr) | 741 | static irqreturn_t sci_tx_interrupt(int irq, void *ptr) |
669 | { | 742 | { |
670 | struct uart_port *port = ptr; | 743 | struct uart_port *port = ptr; |
744 | unsigned long flags; | ||
671 | 745 | ||
672 | spin_lock_irq(&port->lock); | 746 | spin_lock_irqsave(&port->lock, flags); |
673 | sci_transmit_chars(port); | 747 | sci_transmit_chars(port); |
674 | spin_unlock_irq(&port->lock); | 748 | spin_unlock_irqrestore(&port->lock, flags); |
675 | 749 | ||
676 | return IRQ_HANDLED; | 750 | return IRQ_HANDLED; |
677 | } | 751 | } |
@@ -711,32 +785,53 @@ static irqreturn_t sci_br_interrupt(int irq, void *ptr) | |||
711 | return IRQ_HANDLED; | 785 | return IRQ_HANDLED; |
712 | } | 786 | } |
713 | 787 | ||
788 | static inline unsigned long port_rx_irq_mask(struct uart_port *port) | ||
789 | { | ||
790 | /* | ||
791 | * Not all ports (such as SCIFA) will support REIE. Rather than | ||
792 | * special-casing the port type, we check the port initialization | ||
793 | * IRQ enable mask to see whether the IRQ is desired at all. If | ||
794 | * it's unset, it's logically inferred that there's no point in | ||
795 | * testing for it. | ||
796 | */ | ||
797 | return SCSCR_RIE | (to_sci_port(port)->scscr & SCSR_REIE); | ||
798 | } | ||
799 | |||
714 | static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) | 800 | static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) |
715 | { | 801 | { |
716 | unsigned short ssr_status, scr_status; | 802 | unsigned short ssr_status, scr_status, err_enabled; |
717 | struct uart_port *port = ptr; | 803 | struct uart_port *port = ptr; |
804 | struct sci_port *s = to_sci_port(port); | ||
718 | irqreturn_t ret = IRQ_NONE; | 805 | irqreturn_t ret = IRQ_NONE; |
719 | 806 | ||
720 | ssr_status = sci_in(port, SCxSR); | 807 | ssr_status = sci_in(port, SCxSR); |
721 | scr_status = sci_in(port, SCSCR); | 808 | scr_status = sci_in(port, SCSCR); |
809 | err_enabled = scr_status & port_rx_irq_mask(port); | ||
722 | 810 | ||
723 | /* Tx Interrupt */ | 811 | /* Tx Interrupt */ |
724 | if ((ssr_status & 0x0020) && (scr_status & SCSCR_TIE)) | 812 | if ((ssr_status & SCxSR_TDxE(port)) && (scr_status & SCSCR_TIE) && |
813 | !s->chan_tx) | ||
725 | ret = sci_tx_interrupt(irq, ptr); | 814 | ret = sci_tx_interrupt(irq, ptr); |
726 | /* Rx Interrupt */ | 815 | |
727 | if ((ssr_status & 0x0002) && (scr_status & SCSCR_RIE)) | 816 | /* |
817 | * Rx Interrupt: if we're using DMA, the DMA controller clears RDF / | ||
818 | * DR flags | ||
819 | */ | ||
820 | if (((ssr_status & SCxSR_RDxF(port)) || s->chan_rx) && | ||
821 | (scr_status & SCSCR_RIE)) | ||
728 | ret = sci_rx_interrupt(irq, ptr); | 822 | ret = sci_rx_interrupt(irq, ptr); |
823 | |||
729 | /* Error Interrupt */ | 824 | /* Error Interrupt */ |
730 | if ((ssr_status & 0x0080) && (scr_status & SCSCR_REIE)) | 825 | if ((ssr_status & SCxSR_ERRORS(port)) && err_enabled) |
731 | ret = sci_er_interrupt(irq, ptr); | 826 | ret = sci_er_interrupt(irq, ptr); |
827 | |||
732 | /* Break Interrupt */ | 828 | /* Break Interrupt */ |
733 | if ((ssr_status & 0x0010) && (scr_status & SCSCR_REIE)) | 829 | if ((ssr_status & SCxSR_BRK(port)) && err_enabled) |
734 | ret = sci_br_interrupt(irq, ptr); | 830 | ret = sci_br_interrupt(irq, ptr); |
735 | 831 | ||
736 | return ret; | 832 | return ret; |
737 | } | 833 | } |
738 | 834 | ||
739 | #ifdef CONFIG_HAVE_CLK | ||
740 | /* | 835 | /* |
741 | * Here we define a transistion notifier so that we can update all of our | 836 | * Here we define a transistion notifier so that we can update all of our |
742 | * ports' baud rate when the peripheral clock changes. | 837 | * ports' baud rate when the peripheral clock changes. |
@@ -753,8 +848,7 @@ static int sci_notifier(struct notifier_block *self, | |||
753 | (phase == CPUFREQ_RESUMECHANGE)) { | 848 | (phase == CPUFREQ_RESUMECHANGE)) { |
754 | spin_lock_irqsave(&priv->lock, flags); | 849 | spin_lock_irqsave(&priv->lock, flags); |
755 | list_for_each_entry(sci_port, &priv->ports, node) | 850 | list_for_each_entry(sci_port, &priv->ports, node) |
756 | sci_port->port.uartclk = clk_get_rate(sci_port->dclk); | 851 | sci_port->port.uartclk = clk_get_rate(sci_port->iclk); |
757 | |||
758 | spin_unlock_irqrestore(&priv->lock, flags); | 852 | spin_unlock_irqrestore(&priv->lock, flags); |
759 | } | 853 | } |
760 | 854 | ||
@@ -765,23 +859,18 @@ static void sci_clk_enable(struct uart_port *port) | |||
765 | { | 859 | { |
766 | struct sci_port *sci_port = to_sci_port(port); | 860 | struct sci_port *sci_port = to_sci_port(port); |
767 | 861 | ||
768 | clk_enable(sci_port->dclk); | 862 | clk_enable(sci_port->iclk); |
769 | sci_port->port.uartclk = clk_get_rate(sci_port->dclk); | 863 | sci_port->port.uartclk = clk_get_rate(sci_port->iclk); |
770 | 864 | clk_enable(sci_port->fclk); | |
771 | if (sci_port->iclk) | ||
772 | clk_enable(sci_port->iclk); | ||
773 | } | 865 | } |
774 | 866 | ||
775 | static void sci_clk_disable(struct uart_port *port) | 867 | static void sci_clk_disable(struct uart_port *port) |
776 | { | 868 | { |
777 | struct sci_port *sci_port = to_sci_port(port); | 869 | struct sci_port *sci_port = to_sci_port(port); |
778 | 870 | ||
779 | if (sci_port->iclk) | 871 | clk_disable(sci_port->fclk); |
780 | clk_disable(sci_port->iclk); | 872 | clk_disable(sci_port->iclk); |
781 | |||
782 | clk_disable(sci_port->dclk); | ||
783 | } | 873 | } |
784 | #endif | ||
785 | 874 | ||
786 | static int sci_request_irq(struct sci_port *port) | 875 | static int sci_request_irq(struct sci_port *port) |
787 | { | 876 | { |
@@ -836,8 +925,10 @@ static void sci_free_irq(struct sci_port *port) | |||
836 | 925 | ||
837 | static unsigned int sci_tx_empty(struct uart_port *port) | 926 | static unsigned int sci_tx_empty(struct uart_port *port) |
838 | { | 927 | { |
839 | /* Can't detect */ | 928 | unsigned short status = sci_in(port, SCxSR); |
840 | return TIOCSER_TEMT; | 929 | unsigned short in_tx_fifo = scif_txfill(port); |
930 | |||
931 | return (status & SCxSR_TEND(port)) && !in_tx_fifo ? TIOCSER_TEMT : 0; | ||
841 | } | 932 | } |
842 | 933 | ||
843 | static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl) | 934 | static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl) |
@@ -849,20 +940,314 @@ static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
849 | 940 | ||
850 | static unsigned int sci_get_mctrl(struct uart_port *port) | 941 | static unsigned int sci_get_mctrl(struct uart_port *port) |
851 | { | 942 | { |
852 | /* This routine is used for geting signals of: DTR, DCD, DSR, RI, | 943 | /* This routine is used for getting signals of: DTR, DCD, DSR, RI, |
853 | and CTS/RTS */ | 944 | and CTS/RTS */ |
854 | 945 | ||
855 | return TIOCM_DTR | TIOCM_RTS | TIOCM_DSR; | 946 | return TIOCM_DTR | TIOCM_RTS | TIOCM_DSR; |
856 | } | 947 | } |
857 | 948 | ||
949 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | ||
950 | static void sci_dma_tx_complete(void *arg) | ||
951 | { | ||
952 | struct sci_port *s = arg; | ||
953 | struct uart_port *port = &s->port; | ||
954 | struct circ_buf *xmit = &port->state->xmit; | ||
955 | unsigned long flags; | ||
956 | |||
957 | dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); | ||
958 | |||
959 | spin_lock_irqsave(&port->lock, flags); | ||
960 | |||
961 | xmit->tail += sg_dma_len(&s->sg_tx); | ||
962 | xmit->tail &= UART_XMIT_SIZE - 1; | ||
963 | |||
964 | port->icount.tx += sg_dma_len(&s->sg_tx); | ||
965 | |||
966 | async_tx_ack(s->desc_tx); | ||
967 | s->cookie_tx = -EINVAL; | ||
968 | s->desc_tx = NULL; | ||
969 | |||
970 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
971 | uart_write_wakeup(port); | ||
972 | |||
973 | if (!uart_circ_empty(xmit)) { | ||
974 | schedule_work(&s->work_tx); | ||
975 | } else if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { | ||
976 | u16 ctrl = sci_in(port, SCSCR); | ||
977 | sci_out(port, SCSCR, ctrl & ~SCSCR_TIE); | ||
978 | } | ||
979 | |||
980 | spin_unlock_irqrestore(&port->lock, flags); | ||
981 | } | ||
982 | |||
983 | /* Locking: called with port lock held */ | ||
984 | static int sci_dma_rx_push(struct sci_port *s, struct tty_struct *tty, | ||
985 | size_t count) | ||
986 | { | ||
987 | struct uart_port *port = &s->port; | ||
988 | int i, active, room; | ||
989 | |||
990 | room = tty_buffer_request_room(tty, count); | ||
991 | |||
992 | if (s->active_rx == s->cookie_rx[0]) { | ||
993 | active = 0; | ||
994 | } else if (s->active_rx == s->cookie_rx[1]) { | ||
995 | active = 1; | ||
996 | } else { | ||
997 | dev_err(port->dev, "cookie %d not found!\n", s->active_rx); | ||
998 | return 0; | ||
999 | } | ||
1000 | |||
1001 | if (room < count) | ||
1002 | dev_warn(port->dev, "Rx overrun: dropping %u bytes\n", | ||
1003 | count - room); | ||
1004 | if (!room) | ||
1005 | return room; | ||
1006 | |||
1007 | for (i = 0; i < room; i++) | ||
1008 | tty_insert_flip_char(tty, ((u8 *)sg_virt(&s->sg_rx[active]))[i], | ||
1009 | TTY_NORMAL); | ||
1010 | |||
1011 | port->icount.rx += room; | ||
1012 | |||
1013 | return room; | ||
1014 | } | ||
1015 | |||
1016 | static void sci_dma_rx_complete(void *arg) | ||
1017 | { | ||
1018 | struct sci_port *s = arg; | ||
1019 | struct uart_port *port = &s->port; | ||
1020 | struct tty_struct *tty = port->state->port.tty; | ||
1021 | unsigned long flags; | ||
1022 | int count; | ||
1023 | |||
1024 | dev_dbg(port->dev, "%s(%d) active #%d\n", __func__, port->line, s->active_rx); | ||
1025 | |||
1026 | spin_lock_irqsave(&port->lock, flags); | ||
1027 | |||
1028 | count = sci_dma_rx_push(s, tty, s->buf_len_rx); | ||
1029 | |||
1030 | mod_timer(&s->rx_timer, jiffies + s->rx_timeout); | ||
1031 | |||
1032 | spin_unlock_irqrestore(&port->lock, flags); | ||
1033 | |||
1034 | if (count) | ||
1035 | tty_flip_buffer_push(tty); | ||
1036 | |||
1037 | schedule_work(&s->work_rx); | ||
1038 | } | ||
1039 | |||
1040 | static void sci_start_rx(struct uart_port *port); | ||
1041 | static void sci_start_tx(struct uart_port *port); | ||
1042 | |||
1043 | static void sci_rx_dma_release(struct sci_port *s, bool enable_pio) | ||
1044 | { | ||
1045 | struct dma_chan *chan = s->chan_rx; | ||
1046 | struct uart_port *port = &s->port; | ||
1047 | |||
1048 | s->chan_rx = NULL; | ||
1049 | s->cookie_rx[0] = s->cookie_rx[1] = -EINVAL; | ||
1050 | dma_release_channel(chan); | ||
1051 | if (sg_dma_address(&s->sg_rx[0])) | ||
1052 | dma_free_coherent(port->dev, s->buf_len_rx * 2, | ||
1053 | sg_virt(&s->sg_rx[0]), sg_dma_address(&s->sg_rx[0])); | ||
1054 | if (enable_pio) | ||
1055 | sci_start_rx(port); | ||
1056 | } | ||
1057 | |||
1058 | static void sci_tx_dma_release(struct sci_port *s, bool enable_pio) | ||
1059 | { | ||
1060 | struct dma_chan *chan = s->chan_tx; | ||
1061 | struct uart_port *port = &s->port; | ||
1062 | |||
1063 | s->chan_tx = NULL; | ||
1064 | s->cookie_tx = -EINVAL; | ||
1065 | dma_release_channel(chan); | ||
1066 | if (enable_pio) | ||
1067 | sci_start_tx(port); | ||
1068 | } | ||
1069 | |||
1070 | static void sci_submit_rx(struct sci_port *s) | ||
1071 | { | ||
1072 | struct dma_chan *chan = s->chan_rx; | ||
1073 | int i; | ||
1074 | |||
1075 | for (i = 0; i < 2; i++) { | ||
1076 | struct scatterlist *sg = &s->sg_rx[i]; | ||
1077 | struct dma_async_tx_descriptor *desc; | ||
1078 | |||
1079 | desc = chan->device->device_prep_slave_sg(chan, | ||
1080 | sg, 1, DMA_FROM_DEVICE, DMA_PREP_INTERRUPT); | ||
1081 | |||
1082 | if (desc) { | ||
1083 | s->desc_rx[i] = desc; | ||
1084 | desc->callback = sci_dma_rx_complete; | ||
1085 | desc->callback_param = s; | ||
1086 | s->cookie_rx[i] = desc->tx_submit(desc); | ||
1087 | } | ||
1088 | |||
1089 | if (!desc || s->cookie_rx[i] < 0) { | ||
1090 | if (i) { | ||
1091 | async_tx_ack(s->desc_rx[0]); | ||
1092 | s->cookie_rx[0] = -EINVAL; | ||
1093 | } | ||
1094 | if (desc) { | ||
1095 | async_tx_ack(desc); | ||
1096 | s->cookie_rx[i] = -EINVAL; | ||
1097 | } | ||
1098 | dev_warn(s->port.dev, | ||
1099 | "failed to re-start DMA, using PIO\n"); | ||
1100 | sci_rx_dma_release(s, true); | ||
1101 | return; | ||
1102 | } | ||
1103 | dev_dbg(s->port.dev, "%s(): cookie %d to #%d\n", __func__, | ||
1104 | s->cookie_rx[i], i); | ||
1105 | } | ||
1106 | |||
1107 | s->active_rx = s->cookie_rx[0]; | ||
1108 | |||
1109 | dma_async_issue_pending(chan); | ||
1110 | } | ||
1111 | |||
1112 | static void work_fn_rx(struct work_struct *work) | ||
1113 | { | ||
1114 | struct sci_port *s = container_of(work, struct sci_port, work_rx); | ||
1115 | struct uart_port *port = &s->port; | ||
1116 | struct dma_async_tx_descriptor *desc; | ||
1117 | int new; | ||
1118 | |||
1119 | if (s->active_rx == s->cookie_rx[0]) { | ||
1120 | new = 0; | ||
1121 | } else if (s->active_rx == s->cookie_rx[1]) { | ||
1122 | new = 1; | ||
1123 | } else { | ||
1124 | dev_err(port->dev, "cookie %d not found!\n", s->active_rx); | ||
1125 | return; | ||
1126 | } | ||
1127 | desc = s->desc_rx[new]; | ||
1128 | |||
1129 | if (dma_async_is_tx_complete(s->chan_rx, s->active_rx, NULL, NULL) != | ||
1130 | DMA_SUCCESS) { | ||
1131 | /* Handle incomplete DMA receive */ | ||
1132 | struct tty_struct *tty = port->state->port.tty; | ||
1133 | struct dma_chan *chan = s->chan_rx; | ||
1134 | struct sh_desc *sh_desc = container_of(desc, struct sh_desc, | ||
1135 | async_tx); | ||
1136 | unsigned long flags; | ||
1137 | int count; | ||
1138 | |||
1139 | chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); | ||
1140 | dev_dbg(port->dev, "Read %u bytes with cookie %d\n", | ||
1141 | sh_desc->partial, sh_desc->cookie); | ||
1142 | |||
1143 | spin_lock_irqsave(&port->lock, flags); | ||
1144 | count = sci_dma_rx_push(s, tty, sh_desc->partial); | ||
1145 | spin_unlock_irqrestore(&port->lock, flags); | ||
1146 | |||
1147 | if (count) | ||
1148 | tty_flip_buffer_push(tty); | ||
1149 | |||
1150 | sci_submit_rx(s); | ||
1151 | |||
1152 | return; | ||
1153 | } | ||
1154 | |||
1155 | s->cookie_rx[new] = desc->tx_submit(desc); | ||
1156 | if (s->cookie_rx[new] < 0) { | ||
1157 | dev_warn(port->dev, "Failed submitting Rx DMA descriptor\n"); | ||
1158 | sci_rx_dma_release(s, true); | ||
1159 | return; | ||
1160 | } | ||
1161 | |||
1162 | s->active_rx = s->cookie_rx[!new]; | ||
1163 | |||
1164 | dev_dbg(port->dev, "%s: cookie %d #%d, new active #%d\n", __func__, | ||
1165 | s->cookie_rx[new], new, s->active_rx); | ||
1166 | } | ||
1167 | |||
1168 | static void work_fn_tx(struct work_struct *work) | ||
1169 | { | ||
1170 | struct sci_port *s = container_of(work, struct sci_port, work_tx); | ||
1171 | struct dma_async_tx_descriptor *desc; | ||
1172 | struct dma_chan *chan = s->chan_tx; | ||
1173 | struct uart_port *port = &s->port; | ||
1174 | struct circ_buf *xmit = &port->state->xmit; | ||
1175 | struct scatterlist *sg = &s->sg_tx; | ||
1176 | |||
1177 | /* | ||
1178 | * DMA is idle now. | ||
1179 | * Port xmit buffer is already mapped, and it is one page... Just adjust | ||
1180 | * offsets and lengths. Since it is a circular buffer, we have to | ||
1181 | * transmit till the end, and then the rest. Take the port lock to get a | ||
1182 | * consistent xmit buffer state. | ||
1183 | */ | ||
1184 | spin_lock_irq(&port->lock); | ||
1185 | sg->offset = xmit->tail & (UART_XMIT_SIZE - 1); | ||
1186 | sg_dma_address(sg) = (sg_dma_address(sg) & ~(UART_XMIT_SIZE - 1)) + | ||
1187 | sg->offset; | ||
1188 | sg_dma_len(sg) = min((int)CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE), | ||
1189 | CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE)); | ||
1190 | spin_unlock_irq(&port->lock); | ||
1191 | |||
1192 | BUG_ON(!sg_dma_len(sg)); | ||
1193 | |||
1194 | desc = chan->device->device_prep_slave_sg(chan, | ||
1195 | sg, s->sg_len_tx, DMA_TO_DEVICE, | ||
1196 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
1197 | if (!desc) { | ||
1198 | /* switch to PIO */ | ||
1199 | sci_tx_dma_release(s, true); | ||
1200 | return; | ||
1201 | } | ||
1202 | |||
1203 | dma_sync_sg_for_device(port->dev, sg, 1, DMA_TO_DEVICE); | ||
1204 | |||
1205 | spin_lock_irq(&port->lock); | ||
1206 | s->desc_tx = desc; | ||
1207 | desc->callback = sci_dma_tx_complete; | ||
1208 | desc->callback_param = s; | ||
1209 | spin_unlock_irq(&port->lock); | ||
1210 | s->cookie_tx = desc->tx_submit(desc); | ||
1211 | if (s->cookie_tx < 0) { | ||
1212 | dev_warn(port->dev, "Failed submitting Tx DMA descriptor\n"); | ||
1213 | /* switch to PIO */ | ||
1214 | sci_tx_dma_release(s, true); | ||
1215 | return; | ||
1216 | } | ||
1217 | |||
1218 | dev_dbg(port->dev, "%s: %p: %d...%d, cookie %d\n", __func__, | ||
1219 | xmit->buf, xmit->tail, xmit->head, s->cookie_tx); | ||
1220 | |||
1221 | dma_async_issue_pending(chan); | ||
1222 | } | ||
1223 | #endif | ||
1224 | |||
858 | static void sci_start_tx(struct uart_port *port) | 1225 | static void sci_start_tx(struct uart_port *port) |
859 | { | 1226 | { |
1227 | struct sci_port *s = to_sci_port(port); | ||
860 | unsigned short ctrl; | 1228 | unsigned short ctrl; |
861 | 1229 | ||
862 | /* Set TIE (Transmit Interrupt Enable) bit in SCSCR */ | 1230 | #ifdef CONFIG_SERIAL_SH_SCI_DMA |
863 | ctrl = sci_in(port, SCSCR); | 1231 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { |
864 | ctrl |= SCSCR_TIE; | 1232 | u16 new, scr = sci_in(port, SCSCR); |
865 | sci_out(port, SCSCR, ctrl); | 1233 | if (s->chan_tx) |
1234 | new = scr | 0x8000; | ||
1235 | else | ||
1236 | new = scr & ~0x8000; | ||
1237 | if (new != scr) | ||
1238 | sci_out(port, SCSCR, new); | ||
1239 | } | ||
1240 | |||
1241 | if (s->chan_tx && !uart_circ_empty(&s->port.state->xmit) && | ||
1242 | s->cookie_tx < 0) | ||
1243 | schedule_work(&s->work_tx); | ||
1244 | #endif | ||
1245 | |||
1246 | if (!s->chan_tx || port->type == PORT_SCIFA || port->type == PORT_SCIFB) { | ||
1247 | /* Set TIE (Transmit Interrupt Enable) bit in SCSCR */ | ||
1248 | ctrl = sci_in(port, SCSCR); | ||
1249 | sci_out(port, SCSCR, ctrl | SCSCR_TIE); | ||
1250 | } | ||
866 | } | 1251 | } |
867 | 1252 | ||
868 | static void sci_stop_tx(struct uart_port *port) | 1253 | static void sci_stop_tx(struct uart_port *port) |
@@ -871,17 +1256,24 @@ static void sci_stop_tx(struct uart_port *port) | |||
871 | 1256 | ||
872 | /* Clear TIE (Transmit Interrupt Enable) bit in SCSCR */ | 1257 | /* Clear TIE (Transmit Interrupt Enable) bit in SCSCR */ |
873 | ctrl = sci_in(port, SCSCR); | 1258 | ctrl = sci_in(port, SCSCR); |
1259 | |||
1260 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) | ||
1261 | ctrl &= ~0x8000; | ||
1262 | |||
874 | ctrl &= ~SCSCR_TIE; | 1263 | ctrl &= ~SCSCR_TIE; |
1264 | |||
875 | sci_out(port, SCSCR, ctrl); | 1265 | sci_out(port, SCSCR, ctrl); |
876 | } | 1266 | } |
877 | 1267 | ||
878 | static void sci_start_rx(struct uart_port *port, unsigned int tty_start) | 1268 | static void sci_start_rx(struct uart_port *port) |
879 | { | 1269 | { |
880 | unsigned short ctrl; | 1270 | unsigned short ctrl; |
881 | 1271 | ||
882 | /* Set RIE (Receive Interrupt Enable) bit in SCSCR */ | 1272 | ctrl = sci_in(port, SCSCR) | port_rx_irq_mask(port); |
883 | ctrl = sci_in(port, SCSCR); | 1273 | |
884 | ctrl |= SCSCR_RIE | SCSCR_REIE; | 1274 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) |
1275 | ctrl &= ~0x4000; | ||
1276 | |||
885 | sci_out(port, SCSCR, ctrl); | 1277 | sci_out(port, SCSCR, ctrl); |
886 | } | 1278 | } |
887 | 1279 | ||
@@ -889,9 +1281,13 @@ static void sci_stop_rx(struct uart_port *port) | |||
889 | { | 1281 | { |
890 | unsigned short ctrl; | 1282 | unsigned short ctrl; |
891 | 1283 | ||
892 | /* Clear RIE (Receive Interrupt Enable) bit in SCSCR */ | ||
893 | ctrl = sci_in(port, SCSCR); | 1284 | ctrl = sci_in(port, SCSCR); |
894 | ctrl &= ~(SCSCR_RIE | SCSCR_REIE); | 1285 | |
1286 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) | ||
1287 | ctrl &= ~0x4000; | ||
1288 | |||
1289 | ctrl &= ~port_rx_irq_mask(port); | ||
1290 | |||
895 | sci_out(port, SCSCR, ctrl); | 1291 | sci_out(port, SCSCR, ctrl); |
896 | } | 1292 | } |
897 | 1293 | ||
@@ -905,16 +1301,157 @@ static void sci_break_ctl(struct uart_port *port, int break_state) | |||
905 | /* Nothing here yet .. */ | 1301 | /* Nothing here yet .. */ |
906 | } | 1302 | } |
907 | 1303 | ||
1304 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | ||
1305 | static bool filter(struct dma_chan *chan, void *slave) | ||
1306 | { | ||
1307 | struct sh_dmae_slave *param = slave; | ||
1308 | |||
1309 | dev_dbg(chan->device->dev, "%s: slave ID %d\n", __func__, | ||
1310 | param->slave_id); | ||
1311 | |||
1312 | if (param->dma_dev == chan->device->dev) { | ||
1313 | chan->private = param; | ||
1314 | return true; | ||
1315 | } else { | ||
1316 | return false; | ||
1317 | } | ||
1318 | } | ||
1319 | |||
1320 | static void rx_timer_fn(unsigned long arg) | ||
1321 | { | ||
1322 | struct sci_port *s = (struct sci_port *)arg; | ||
1323 | struct uart_port *port = &s->port; | ||
1324 | u16 scr = sci_in(port, SCSCR); | ||
1325 | |||
1326 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { | ||
1327 | scr &= ~0x4000; | ||
1328 | enable_irq(s->irqs[1]); | ||
1329 | } | ||
1330 | sci_out(port, SCSCR, scr | SCSCR_RIE); | ||
1331 | dev_dbg(port->dev, "DMA Rx timed out\n"); | ||
1332 | schedule_work(&s->work_rx); | ||
1333 | } | ||
1334 | |||
1335 | static void sci_request_dma(struct uart_port *port) | ||
1336 | { | ||
1337 | struct sci_port *s = to_sci_port(port); | ||
1338 | struct sh_dmae_slave *param; | ||
1339 | struct dma_chan *chan; | ||
1340 | dma_cap_mask_t mask; | ||
1341 | int nent; | ||
1342 | |||
1343 | dev_dbg(port->dev, "%s: port %d DMA %p\n", __func__, | ||
1344 | port->line, s->dma_dev); | ||
1345 | |||
1346 | if (!s->dma_dev) | ||
1347 | return; | ||
1348 | |||
1349 | dma_cap_zero(mask); | ||
1350 | dma_cap_set(DMA_SLAVE, mask); | ||
1351 | |||
1352 | param = &s->param_tx; | ||
1353 | |||
1354 | /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_TX */ | ||
1355 | param->slave_id = s->slave_tx; | ||
1356 | param->dma_dev = s->dma_dev; | ||
1357 | |||
1358 | s->cookie_tx = -EINVAL; | ||
1359 | chan = dma_request_channel(mask, filter, param); | ||
1360 | dev_dbg(port->dev, "%s: TX: got channel %p\n", __func__, chan); | ||
1361 | if (chan) { | ||
1362 | s->chan_tx = chan; | ||
1363 | sg_init_table(&s->sg_tx, 1); | ||
1364 | /* UART circular tx buffer is an aligned page. */ | ||
1365 | BUG_ON((int)port->state->xmit.buf & ~PAGE_MASK); | ||
1366 | sg_set_page(&s->sg_tx, virt_to_page(port->state->xmit.buf), | ||
1367 | UART_XMIT_SIZE, (int)port->state->xmit.buf & ~PAGE_MASK); | ||
1368 | nent = dma_map_sg(port->dev, &s->sg_tx, 1, DMA_TO_DEVICE); | ||
1369 | if (!nent) | ||
1370 | sci_tx_dma_release(s, false); | ||
1371 | else | ||
1372 | dev_dbg(port->dev, "%s: mapped %d@%p to %x\n", __func__, | ||
1373 | sg_dma_len(&s->sg_tx), | ||
1374 | port->state->xmit.buf, sg_dma_address(&s->sg_tx)); | ||
1375 | |||
1376 | s->sg_len_tx = nent; | ||
1377 | |||
1378 | INIT_WORK(&s->work_tx, work_fn_tx); | ||
1379 | } | ||
1380 | |||
1381 | param = &s->param_rx; | ||
1382 | |||
1383 | /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_RX */ | ||
1384 | param->slave_id = s->slave_rx; | ||
1385 | param->dma_dev = s->dma_dev; | ||
1386 | |||
1387 | chan = dma_request_channel(mask, filter, param); | ||
1388 | dev_dbg(port->dev, "%s: RX: got channel %p\n", __func__, chan); | ||
1389 | if (chan) { | ||
1390 | dma_addr_t dma[2]; | ||
1391 | void *buf[2]; | ||
1392 | int i; | ||
1393 | |||
1394 | s->chan_rx = chan; | ||
1395 | |||
1396 | s->buf_len_rx = 2 * max(16, (int)port->fifosize); | ||
1397 | buf[0] = dma_alloc_coherent(port->dev, s->buf_len_rx * 2, | ||
1398 | &dma[0], GFP_KERNEL); | ||
1399 | |||
1400 | if (!buf[0]) { | ||
1401 | dev_warn(port->dev, | ||
1402 | "failed to allocate dma buffer, using PIO\n"); | ||
1403 | sci_rx_dma_release(s, true); | ||
1404 | return; | ||
1405 | } | ||
1406 | |||
1407 | buf[1] = buf[0] + s->buf_len_rx; | ||
1408 | dma[1] = dma[0] + s->buf_len_rx; | ||
1409 | |||
1410 | for (i = 0; i < 2; i++) { | ||
1411 | struct scatterlist *sg = &s->sg_rx[i]; | ||
1412 | |||
1413 | sg_init_table(sg, 1); | ||
1414 | sg_set_page(sg, virt_to_page(buf[i]), s->buf_len_rx, | ||
1415 | (int)buf[i] & ~PAGE_MASK); | ||
1416 | sg_dma_address(sg) = dma[i]; | ||
1417 | } | ||
1418 | |||
1419 | INIT_WORK(&s->work_rx, work_fn_rx); | ||
1420 | setup_timer(&s->rx_timer, rx_timer_fn, (unsigned long)s); | ||
1421 | |||
1422 | sci_submit_rx(s); | ||
1423 | } | ||
1424 | } | ||
1425 | |||
1426 | static void sci_free_dma(struct uart_port *port) | ||
1427 | { | ||
1428 | struct sci_port *s = to_sci_port(port); | ||
1429 | |||
1430 | if (!s->dma_dev) | ||
1431 | return; | ||
1432 | |||
1433 | if (s->chan_tx) | ||
1434 | sci_tx_dma_release(s, false); | ||
1435 | if (s->chan_rx) | ||
1436 | sci_rx_dma_release(s, false); | ||
1437 | } | ||
1438 | #endif | ||
1439 | |||
908 | static int sci_startup(struct uart_port *port) | 1440 | static int sci_startup(struct uart_port *port) |
909 | { | 1441 | { |
910 | struct sci_port *s = to_sci_port(port); | 1442 | struct sci_port *s = to_sci_port(port); |
911 | 1443 | ||
1444 | dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); | ||
1445 | |||
912 | if (s->enable) | 1446 | if (s->enable) |
913 | s->enable(port); | 1447 | s->enable(port); |
914 | 1448 | ||
915 | sci_request_irq(s); | 1449 | sci_request_irq(s); |
1450 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | ||
1451 | sci_request_dma(port); | ||
1452 | #endif | ||
916 | sci_start_tx(port); | 1453 | sci_start_tx(port); |
917 | sci_start_rx(port, 1); | 1454 | sci_start_rx(port); |
918 | 1455 | ||
919 | return 0; | 1456 | return 0; |
920 | } | 1457 | } |
@@ -923,8 +1460,13 @@ static void sci_shutdown(struct uart_port *port) | |||
923 | { | 1460 | { |
924 | struct sci_port *s = to_sci_port(port); | 1461 | struct sci_port *s = to_sci_port(port); |
925 | 1462 | ||
1463 | dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); | ||
1464 | |||
926 | sci_stop_rx(port); | 1465 | sci_stop_rx(port); |
927 | sci_stop_tx(port); | 1466 | sci_stop_tx(port); |
1467 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | ||
1468 | sci_free_dma(port); | ||
1469 | #endif | ||
928 | sci_free_irq(s); | 1470 | sci_free_irq(s); |
929 | 1471 | ||
930 | if (s->disable) | 1472 | if (s->disable) |
@@ -956,11 +1498,22 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
956 | struct ktermios *old) | 1498 | struct ktermios *old) |
957 | { | 1499 | { |
958 | struct sci_port *s = to_sci_port(port); | 1500 | struct sci_port *s = to_sci_port(port); |
959 | unsigned int status, baud, smr_val; | 1501 | unsigned int status, baud, smr_val, max_baud; |
960 | int t = -1; | 1502 | int t = -1; |
1503 | u16 scfcr = 0; | ||
1504 | |||
1505 | /* | ||
1506 | * earlyprintk comes here early on with port->uartclk set to zero. | ||
1507 | * the clock framework is not up and running at this point so here | ||
1508 | * we assume that 115200 is the maximum baud rate. please note that | ||
1509 | * the baud rate is not programmed during earlyprintk - it is assumed | ||
1510 | * that the previous boot loader has enabled required clocks and | ||
1511 | * setup the baud rate generator hardware for us already. | ||
1512 | */ | ||
1513 | max_baud = port->uartclk ? port->uartclk / 16 : 115200; | ||
961 | 1514 | ||
962 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); | 1515 | baud = uart_get_baud_rate(port, termios, old, 0, max_baud); |
963 | if (likely(baud)) | 1516 | if (likely(baud && port->uartclk)) |
964 | t = sci_scbrr_calc(s->scbrr_algo_id, baud, port->uartclk); | 1517 | t = sci_scbrr_calc(s->scbrr_algo_id, baud, port->uartclk); |
965 | 1518 | ||
966 | do { | 1519 | do { |
@@ -970,7 +1523,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
970 | sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */ | 1523 | sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */ |
971 | 1524 | ||
972 | if (port->type != PORT_SCI) | 1525 | if (port->type != PORT_SCI) |
973 | sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST); | 1526 | sci_out(port, SCFCR, scfcr | SCFCR_RFRST | SCFCR_TFRST); |
974 | 1527 | ||
975 | smr_val = sci_in(port, SCSMR) & 3; | 1528 | smr_val = sci_in(port, SCSMR) & 3; |
976 | if ((termios->c_cflag & CSIZE) == CS7) | 1529 | if ((termios->c_cflag & CSIZE) == CS7) |
@@ -986,6 +1539,9 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
986 | 1539 | ||
987 | sci_out(port, SCSMR, smr_val); | 1540 | sci_out(port, SCSMR, smr_val); |
988 | 1541 | ||
1542 | dev_dbg(port->dev, "%s: SMR %x, t %x, SCSCR %x\n", __func__, smr_val, t, | ||
1543 | SCSCR_INIT(port)); | ||
1544 | |||
989 | if (t > 0) { | 1545 | if (t > 0) { |
990 | if (t >= 256) { | 1546 | if (t >= 256) { |
991 | sci_out(port, SCSMR, (sci_in(port, SCSMR) & ~3) | 1); | 1547 | sci_out(port, SCSMR, (sci_in(port, SCSMR) & ~3) | 1); |
@@ -998,12 +1554,34 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
998 | } | 1554 | } |
999 | 1555 | ||
1000 | sci_init_pins(port, termios->c_cflag); | 1556 | sci_init_pins(port, termios->c_cflag); |
1001 | sci_out(port, SCFCR, (termios->c_cflag & CRTSCTS) ? SCFCR_MCE : 0); | 1557 | sci_out(port, SCFCR, scfcr | ((termios->c_cflag & CRTSCTS) ? SCFCR_MCE : 0)); |
1002 | 1558 | ||
1003 | sci_out(port, SCSCR, s->scscr); | 1559 | sci_out(port, SCSCR, s->scscr); |
1004 | 1560 | ||
1561 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | ||
1562 | /* | ||
1563 | * Calculate delay for 1.5 DMA buffers: see | ||
1564 | * drivers/serial/serial_core.c::uart_update_timeout(). With 10 bits | ||
1565 | * (CS8), 250Hz, 115200 baud and 64 bytes FIFO, the above function | ||
1566 | * calculates 1 jiffie for the data plus 5 jiffies for the "slop(e)." | ||
1567 | * Then below we calculate 3 jiffies (12ms) for 1.5 DMA buffers (3 FIFO | ||
1568 | * sizes), but it has been found out experimentally, that this is not | ||
1569 | * enough: the driver too often needlessly runs on a DMA timeout. 20ms | ||
1570 | * as a minimum seem to work perfectly. | ||
1571 | */ | ||
1572 | if (s->chan_rx) { | ||
1573 | s->rx_timeout = (port->timeout - HZ / 50) * s->buf_len_rx * 3 / | ||
1574 | port->fifosize / 2; | ||
1575 | dev_dbg(port->dev, | ||
1576 | "DMA Rx t-out %ums, tty t-out %u jiffies\n", | ||
1577 | s->rx_timeout * 1000 / HZ, port->timeout); | ||
1578 | if (s->rx_timeout < msecs_to_jiffies(20)) | ||
1579 | s->rx_timeout = msecs_to_jiffies(20); | ||
1580 | } | ||
1581 | #endif | ||
1582 | |||
1005 | if ((termios->c_cflag & CREAD) != 0) | 1583 | if ((termios->c_cflag & CREAD) != 0) |
1006 | sci_start_rx(port, 0); | 1584 | sci_start_rx(port); |
1007 | } | 1585 | } |
1008 | 1586 | ||
1009 | static const char *sci_type(struct uart_port *port) | 1587 | static const char *sci_type(struct uart_port *port) |
@@ -1017,6 +1595,8 @@ static const char *sci_type(struct uart_port *port) | |||
1017 | return "scif"; | 1595 | return "scif"; |
1018 | case PORT_SCIFA: | 1596 | case PORT_SCIFA: |
1019 | return "scifa"; | 1597 | return "scifa"; |
1598 | case PORT_SCIFB: | ||
1599 | return "scifb"; | ||
1020 | } | 1600 | } |
1021 | 1601 | ||
1022 | return NULL; | 1602 | return NULL; |
@@ -1093,45 +1673,79 @@ static struct uart_ops sci_uart_ops = { | |||
1093 | #endif | 1673 | #endif |
1094 | }; | 1674 | }; |
1095 | 1675 | ||
1096 | static void __devinit sci_init_single(struct platform_device *dev, | 1676 | static int __devinit sci_init_single(struct platform_device *dev, |
1097 | struct sci_port *sci_port, | 1677 | struct sci_port *sci_port, |
1098 | unsigned int index, | 1678 | unsigned int index, |
1099 | struct plat_sci_port *p) | 1679 | struct plat_sci_port *p) |
1100 | { | 1680 | { |
1101 | sci_port->port.ops = &sci_uart_ops; | 1681 | struct uart_port *port = &sci_port->port; |
1102 | sci_port->port.iotype = UPIO_MEM; | ||
1103 | sci_port->port.line = index; | ||
1104 | sci_port->port.fifosize = 1; | ||
1105 | 1682 | ||
1106 | #if defined(__H8300H__) || defined(__H8300S__) | 1683 | port->ops = &sci_uart_ops; |
1107 | #ifdef __H8300S__ | 1684 | port->iotype = UPIO_MEM; |
1108 | sci_port->enable = h8300_sci_enable; | 1685 | port->line = index; |
1109 | sci_port->disable = h8300_sci_disable; | 1686 | |
1110 | #endif | 1687 | switch (p->type) { |
1111 | sci_port->port.uartclk = CONFIG_CPU_CLOCK; | 1688 | case PORT_SCIFB: |
1112 | #elif defined(CONFIG_HAVE_CLK) | 1689 | port->fifosize = 256; |
1113 | sci_port->iclk = p->clk ? clk_get(&dev->dev, p->clk) : NULL; | 1690 | break; |
1114 | sci_port->dclk = clk_get(&dev->dev, "peripheral_clk"); | 1691 | case PORT_SCIFA: |
1115 | sci_port->enable = sci_clk_enable; | 1692 | port->fifosize = 64; |
1116 | sci_port->disable = sci_clk_disable; | 1693 | break; |
1117 | #else | 1694 | case PORT_SCIF: |
1118 | #error "Need a valid uartclk" | 1695 | port->fifosize = 16; |
1119 | #endif | 1696 | break; |
1697 | default: | ||
1698 | port->fifosize = 1; | ||
1699 | break; | ||
1700 | } | ||
1701 | |||
1702 | if (dev) { | ||
1703 | sci_port->iclk = clk_get(&dev->dev, "sci_ick"); | ||
1704 | if (IS_ERR(sci_port->iclk)) { | ||
1705 | sci_port->iclk = clk_get(&dev->dev, "peripheral_clk"); | ||
1706 | if (IS_ERR(sci_port->iclk)) { | ||
1707 | dev_err(&dev->dev, "can't get iclk\n"); | ||
1708 | return PTR_ERR(sci_port->iclk); | ||
1709 | } | ||
1710 | } | ||
1711 | |||
1712 | /* | ||
1713 | * The function clock is optional, ignore it if we can't | ||
1714 | * find it. | ||
1715 | */ | ||
1716 | sci_port->fclk = clk_get(&dev->dev, "sci_fck"); | ||
1717 | if (IS_ERR(sci_port->fclk)) | ||
1718 | sci_port->fclk = NULL; | ||
1719 | |||
1720 | sci_port->enable = sci_clk_enable; | ||
1721 | sci_port->disable = sci_clk_disable; | ||
1722 | port->dev = &dev->dev; | ||
1723 | } | ||
1120 | 1724 | ||
1121 | sci_port->break_timer.data = (unsigned long)sci_port; | 1725 | sci_port->break_timer.data = (unsigned long)sci_port; |
1122 | sci_port->break_timer.function = sci_break_timer; | 1726 | sci_port->break_timer.function = sci_break_timer; |
1123 | init_timer(&sci_port->break_timer); | 1727 | init_timer(&sci_port->break_timer); |
1124 | 1728 | ||
1125 | sci_port->port.mapbase = p->mapbase; | 1729 | port->mapbase = p->mapbase; |
1126 | sci_port->port.membase = p->membase; | 1730 | port->membase = p->membase; |
1127 | 1731 | ||
1732 | port->irq = p->irqs[SCIx_TXI_IRQ]; | ||
1733 | port->flags = p->flags; | ||
1734 | sci_port->type = port->type = p->type; | ||
1128 | sci_port->scscr = p->scscr; | 1735 | sci_port->scscr = p->scscr; |
1129 | sci_port->port.irq = p->irqs[SCIx_TXI_IRQ]; | 1736 | sci_port->scbrr_algo_id = p->scbrr_algo_id; |
1130 | sci_port->port.flags = p->flags; | 1737 | |
1131 | sci_port->port.dev = &dev->dev; | 1738 | #ifdef CONFIG_SERIAL_SH_SCI_DMA |
1132 | sci_port->type = sci_port->port.type = p->type; | 1739 | sci_port->dma_dev = p->dma_dev; |
1740 | sci_port->slave_tx = p->dma_slave_tx; | ||
1741 | sci_port->slave_rx = p->dma_slave_rx; | ||
1742 | |||
1743 | dev_dbg(port->dev, "%s: DMA device %p, tx %d, rx %d\n", __func__, | ||
1744 | p->dma_dev, p->dma_slave_tx, p->dma_slave_rx); | ||
1745 | #endif | ||
1133 | 1746 | ||
1134 | memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs)); | 1747 | memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs)); |
1748 | return 0; | ||
1135 | } | 1749 | } |
1136 | 1750 | ||
1137 | #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE | 1751 | #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE |
@@ -1168,11 +1782,11 @@ static void serial_console_write(struct console *co, const char *s, | |||
1168 | while ((sci_in(port, SCxSR) & bits) != bits) | 1782 | while ((sci_in(port, SCxSR) & bits) != bits) |
1169 | cpu_relax(); | 1783 | cpu_relax(); |
1170 | 1784 | ||
1171 | if (sci_port->disable); | 1785 | if (sci_port->disable) |
1172 | sci_port->disable(port); | 1786 | sci_port->disable(port); |
1173 | } | 1787 | } |
1174 | 1788 | ||
1175 | static int __init serial_console_setup(struct console *co, char *options) | 1789 | static int __devinit serial_console_setup(struct console *co, char *options) |
1176 | { | 1790 | { |
1177 | struct sci_port *sci_port; | 1791 | struct sci_port *sci_port; |
1178 | struct uart_port *port; | 1792 | struct uart_port *port; |
@@ -1190,9 +1804,14 @@ static int __init serial_console_setup(struct console *co, char *options) | |||
1190 | if (co->index >= SCI_NPORTS) | 1804 | if (co->index >= SCI_NPORTS) |
1191 | co->index = 0; | 1805 | co->index = 0; |
1192 | 1806 | ||
1193 | sci_port = &sci_ports[co->index]; | 1807 | if (co->data) { |
1194 | port = &sci_port->port; | 1808 | port = co->data; |
1195 | co->data = port; | 1809 | sci_port = to_sci_port(port); |
1810 | } else { | ||
1811 | sci_port = &sci_ports[co->index]; | ||
1812 | port = &sci_port->port; | ||
1813 | co->data = port; | ||
1814 | } | ||
1196 | 1815 | ||
1197 | /* | 1816 | /* |
1198 | * Also need to check port->type, we don't actually have any | 1817 | * Also need to check port->type, we don't actually have any |
@@ -1236,6 +1855,15 @@ static int __init sci_console_init(void) | |||
1236 | return 0; | 1855 | return 0; |
1237 | } | 1856 | } |
1238 | console_initcall(sci_console_init); | 1857 | console_initcall(sci_console_init); |
1858 | |||
1859 | static struct sci_port early_serial_port; | ||
1860 | static struct console early_serial_console = { | ||
1861 | .name = "early_ttySC", | ||
1862 | .write = serial_console_write, | ||
1863 | .flags = CON_PRINTBUFFER, | ||
1864 | }; | ||
1865 | static char early_serial_buf[32]; | ||
1866 | |||
1239 | #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ | 1867 | #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ |
1240 | 1868 | ||
1241 | #if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) | 1869 | #if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) |
@@ -1264,14 +1892,14 @@ static int sci_remove(struct platform_device *dev) | |||
1264 | struct sci_port *p; | 1892 | struct sci_port *p; |
1265 | unsigned long flags; | 1893 | unsigned long flags; |
1266 | 1894 | ||
1267 | #ifdef CONFIG_HAVE_CLK | ||
1268 | cpufreq_unregister_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER); | 1895 | cpufreq_unregister_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER); |
1269 | #endif | ||
1270 | 1896 | ||
1271 | spin_lock_irqsave(&priv->lock, flags); | 1897 | spin_lock_irqsave(&priv->lock, flags); |
1272 | list_for_each_entry(p, &priv->ports, node) | 1898 | list_for_each_entry(p, &priv->ports, node) { |
1273 | uart_remove_one_port(&sci_uart_driver, &p->port); | 1899 | uart_remove_one_port(&sci_uart_driver, &p->port); |
1274 | 1900 | clk_put(p->iclk); | |
1901 | clk_put(p->fclk); | ||
1902 | } | ||
1275 | spin_unlock_irqrestore(&priv->lock, flags); | 1903 | spin_unlock_irqrestore(&priv->lock, flags); |
1276 | 1904 | ||
1277 | kfree(priv); | 1905 | kfree(priv); |
@@ -1297,7 +1925,9 @@ static int __devinit sci_probe_single(struct platform_device *dev, | |||
1297 | return 0; | 1925 | return 0; |
1298 | } | 1926 | } |
1299 | 1927 | ||
1300 | sci_init_single(dev, sciport, index, p); | 1928 | ret = sci_init_single(dev, sciport, index, p); |
1929 | if (ret) | ||
1930 | return ret; | ||
1301 | 1931 | ||
1302 | ret = uart_add_one_port(&sci_uart_driver, &sciport->port); | 1932 | ret = uart_add_one_port(&sci_uart_driver, &sciport->port); |
1303 | if (ret) | 1933 | if (ret) |
@@ -1324,6 +1954,21 @@ static int __devinit sci_probe(struct platform_device *dev) | |||
1324 | struct sh_sci_priv *priv; | 1954 | struct sh_sci_priv *priv; |
1325 | int i, ret = -EINVAL; | 1955 | int i, ret = -EINVAL; |
1326 | 1956 | ||
1957 | #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE | ||
1958 | if (is_early_platform_device(dev)) { | ||
1959 | if (dev->id == -1) | ||
1960 | return -ENOTSUPP; | ||
1961 | early_serial_console.index = dev->id; | ||
1962 | early_serial_console.data = &early_serial_port.port; | ||
1963 | sci_init_single(NULL, &early_serial_port, dev->id, p); | ||
1964 | serial_console_setup(&early_serial_console, early_serial_buf); | ||
1965 | if (!strstr(early_serial_buf, "keep")) | ||
1966 | early_serial_console.flags |= CON_BOOT; | ||
1967 | register_console(&early_serial_console); | ||
1968 | return 0; | ||
1969 | } | ||
1970 | #endif | ||
1971 | |||
1327 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | 1972 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
1328 | if (!priv) | 1973 | if (!priv) |
1329 | return -ENOMEM; | 1974 | return -ENOMEM; |
@@ -1332,10 +1977,8 @@ static int __devinit sci_probe(struct platform_device *dev) | |||
1332 | spin_lock_init(&priv->lock); | 1977 | spin_lock_init(&priv->lock); |
1333 | platform_set_drvdata(dev, priv); | 1978 | platform_set_drvdata(dev, priv); |
1334 | 1979 | ||
1335 | #ifdef CONFIG_HAVE_CLK | ||
1336 | priv->clk_nb.notifier_call = sci_notifier; | 1980 | priv->clk_nb.notifier_call = sci_notifier; |
1337 | cpufreq_register_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER); | 1981 | cpufreq_register_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER); |
1338 | #endif | ||
1339 | 1982 | ||
1340 | if (dev->id != -1) { | 1983 | if (dev->id != -1) { |
1341 | ret = sci_probe_single(dev, dev->id, p, &sci_ports[dev->id]); | 1984 | ret = sci_probe_single(dev, dev->id, p, &sci_ports[dev->id]); |
@@ -1388,14 +2031,14 @@ static int sci_resume(struct device *dev) | |||
1388 | return 0; | 2031 | return 0; |
1389 | } | 2032 | } |
1390 | 2033 | ||
1391 | static struct dev_pm_ops sci_dev_pm_ops = { | 2034 | static const struct dev_pm_ops sci_dev_pm_ops = { |
1392 | .suspend = sci_suspend, | 2035 | .suspend = sci_suspend, |
1393 | .resume = sci_resume, | 2036 | .resume = sci_resume, |
1394 | }; | 2037 | }; |
1395 | 2038 | ||
1396 | static struct platform_driver sci_driver = { | 2039 | static struct platform_driver sci_driver = { |
1397 | .probe = sci_probe, | 2040 | .probe = sci_probe, |
1398 | .remove = __devexit_p(sci_remove), | 2041 | .remove = sci_remove, |
1399 | .driver = { | 2042 | .driver = { |
1400 | .name = "sh-sci", | 2043 | .name = "sh-sci", |
1401 | .owner = THIS_MODULE, | 2044 | .owner = THIS_MODULE, |
@@ -1425,6 +2068,10 @@ static void __exit sci_exit(void) | |||
1425 | uart_unregister_driver(&sci_uart_driver); | 2068 | uart_unregister_driver(&sci_uart_driver); |
1426 | } | 2069 | } |
1427 | 2070 | ||
2071 | #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE | ||
2072 | early_platform_init_buffer("earlyprintk", &sci_driver, | ||
2073 | early_serial_buf, ARRAY_SIZE(early_serial_buf)); | ||
2074 | #endif | ||
1428 | module_init(sci_init); | 2075 | module_init(sci_init); |
1429 | module_exit(sci_exit); | 2076 | module_exit(sci_exit); |
1430 | 2077 | ||
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index 1b2ce1546979..b223d6cbf33a 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h | |||
@@ -1,5 +1,5 @@ | |||
1 | #include <linux/serial_core.h> | 1 | #include <linux/serial_core.h> |
2 | #include <asm/io.h> | 2 | #include <linux/io.h> |
3 | #include <linux/gpio.h> | 3 | #include <linux/gpio.h> |
4 | 4 | ||
5 | #if defined(CONFIG_H83007) || defined(CONFIG_H83068) | 5 | #if defined(CONFIG_H83007) || defined(CONFIG_H83068) |
@@ -21,7 +21,11 @@ | |||
21 | # define SCPCR 0xA4000116 | 21 | # define SCPCR 0xA4000116 |
22 | # define SCPDR 0xA4000136 | 22 | # define SCPDR 0xA4000136 |
23 | #elif defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | 23 | #elif defined(CONFIG_CPU_SUBTYPE_SH7720) || \ |
24 | defined(CONFIG_CPU_SUBTYPE_SH7721) | 24 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ |
25 | defined(CONFIG_ARCH_SH73A0) || \ | ||
26 | defined(CONFIG_ARCH_SH7367) || \ | ||
27 | defined(CONFIG_ARCH_SH7377) || \ | ||
28 | defined(CONFIG_ARCH_SH7372) | ||
25 | # define PORT_PTCR 0xA405011EUL | 29 | # define PORT_PTCR 0xA405011EUL |
26 | # define PORT_PVCR 0xA4050122UL | 30 | # define PORT_PVCR 0xA4050122UL |
27 | # define SCIF_ORER 0x0200 /* overrun error bit */ | 31 | # define SCIF_ORER 0x0200 /* overrun error bit */ |
@@ -83,6 +87,12 @@ | |||
83 | # define H8300_SCI_DR(ch) *(volatile char *)(P1DR + h8300_sci_pins[ch].port) | 87 | # define H8300_SCI_DR(ch) *(volatile char *)(P1DR + h8300_sci_pins[ch].port) |
84 | #elif defined(CONFIG_H8S2678) | 88 | #elif defined(CONFIG_H8S2678) |
85 | # define H8300_SCI_DR(ch) *(volatile char *)(P1DR + h8300_sci_pins[ch].port) | 89 | # define H8300_SCI_DR(ch) *(volatile char *)(P1DR + h8300_sci_pins[ch].port) |
90 | #elif defined(CONFIG_CPU_SUBTYPE_SH7757) | ||
91 | # define SCSPTR0 0xfe4b0020 | ||
92 | # define SCSPTR1 0xfe4b0020 | ||
93 | # define SCSPTR2 0xfe4b0020 | ||
94 | # define SCIF_ORER 0x0001 | ||
95 | # define SCIF_ONLY | ||
86 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) | 96 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) |
87 | # define SCSPTR0 0xffe00024 /* 16 bit SCIF */ | 97 | # define SCSPTR0 0xffe00024 /* 16 bit SCIF */ |
88 | # define SCSPTR1 0xffe08024 /* 16 bit SCIF */ | 98 | # define SCSPTR1 0xffe08024 /* 16 bit SCIF */ |
@@ -159,7 +169,11 @@ | |||
159 | 169 | ||
160 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ | 170 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ |
161 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | 171 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ |
162 | defined(CONFIG_CPU_SUBTYPE_SH7721) | 172 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ |
173 | defined(CONFIG_ARCH_SH73A0) || \ | ||
174 | defined(CONFIG_ARCH_SH7367) || \ | ||
175 | defined(CONFIG_ARCH_SH7377) || \ | ||
176 | defined(CONFIG_ARCH_SH7372) | ||
163 | # define SCIF_ORER 0x0200 | 177 | # define SCIF_ORER 0x0200 |
164 | # define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK | SCIF_ORER) | 178 | # define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK | SCIF_ORER) |
165 | # define SCIF_RFDC_MASK 0x007f | 179 | # define SCIF_RFDC_MASK 0x007f |
@@ -192,7 +206,11 @@ | |||
192 | 206 | ||
193 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ | 207 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ |
194 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | 208 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ |
195 | defined(CONFIG_CPU_SUBTYPE_SH7721) | 209 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ |
210 | defined(CONFIG_ARCH_SH73A0) || \ | ||
211 | defined(CONFIG_ARCH_SH7367) || \ | ||
212 | defined(CONFIG_ARCH_SH7377) || \ | ||
213 | defined(CONFIG_ARCH_SH7372) | ||
196 | # define SCxSR_RDxF_CLEAR(port) (sci_in(port, SCxSR) & 0xfffc) | 214 | # define SCxSR_RDxF_CLEAR(port) (sci_in(port, SCxSR) & 0xfffc) |
197 | # define SCxSR_ERROR_CLEAR(port) (sci_in(port, SCxSR) & 0xfd73) | 215 | # define SCxSR_ERROR_CLEAR(port) (sci_in(port, SCxSR) & 0xfd73) |
198 | # define SCxSR_TDxE_CLEAR(port) (sci_in(port, SCxSR) & 0xffdf) | 216 | # define SCxSR_TDxE_CLEAR(port) (sci_in(port, SCxSR) & 0xffdf) |
@@ -228,7 +246,7 @@ | |||
228 | #define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\ | 246 | #define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\ |
229 | static inline unsigned int sci_##name##_in(struct uart_port *port) \ | 247 | static inline unsigned int sci_##name##_in(struct uart_port *port) \ |
230 | { \ | 248 | { \ |
231 | if (port->type == PORT_SCIF) { \ | 249 | if (port->type == PORT_SCIF || port->type == PORT_SCIFB) { \ |
232 | SCI_IN(scif_size, scif_offset) \ | 250 | SCI_IN(scif_size, scif_offset) \ |
233 | } else { /* PORT_SCI or PORT_SCIFA */ \ | 251 | } else { /* PORT_SCI or PORT_SCIFA */ \ |
234 | SCI_IN(sci_size, sci_offset); \ | 252 | SCI_IN(sci_size, sci_offset); \ |
@@ -236,7 +254,7 @@ | |||
236 | } \ | 254 | } \ |
237 | static inline void sci_##name##_out(struct uart_port *port, unsigned int value) \ | 255 | static inline void sci_##name##_out(struct uart_port *port, unsigned int value) \ |
238 | { \ | 256 | { \ |
239 | if (port->type == PORT_SCIF) { \ | 257 | if (port->type == PORT_SCIF || port->type == PORT_SCIFB) { \ |
240 | SCI_OUT(scif_size, scif_offset, value) \ | 258 | SCI_OUT(scif_size, scif_offset, value) \ |
241 | } else { /* PORT_SCI or PORT_SCIFA */ \ | 259 | } else { /* PORT_SCI or PORT_SCIFA */ \ |
242 | SCI_OUT(sci_size, sci_offset, value); \ | 260 | SCI_OUT(sci_size, sci_offset, value); \ |
@@ -275,7 +293,11 @@ | |||
275 | SCI_OUT(sci_size, sci_offset, value); \ | 293 | SCI_OUT(sci_size, sci_offset, value); \ |
276 | } | 294 | } |
277 | 295 | ||
278 | #ifdef CONFIG_CPU_SH3 | 296 | #if defined(CONFIG_CPU_SH3) || \ |
297 | defined(CONFIG_ARCH_SH73A0) || \ | ||
298 | defined(CONFIG_ARCH_SH7367) || \ | ||
299 | defined(CONFIG_ARCH_SH7377) || \ | ||
300 | defined(CONFIG_ARCH_SH7372) | ||
279 | #if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) | 301 | #if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) |
280 | #define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \ | 302 | #define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \ |
281 | sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \ | 303 | sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \ |
@@ -285,7 +307,15 @@ | |||
285 | CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) | 307 | CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) |
286 | #elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \ | 308 | #elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \ |
287 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | 309 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ |
288 | defined(CONFIG_CPU_SUBTYPE_SH7721) | 310 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ |
311 | defined(CONFIG_ARCH_SH73A0) || \ | ||
312 | defined(CONFIG_ARCH_SH7367) || \ | ||
313 | defined(CONFIG_ARCH_SH7377) | ||
314 | #define SCIF_FNS(name, scif_offset, scif_size) \ | ||
315 | CPU_SCIF_FNS(name, scif_offset, scif_size) | ||
316 | #elif defined(CONFIG_ARCH_SH7372) | ||
317 | #define SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scifb_offset, sh4_scifb_size) \ | ||
318 | CPU_SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scifb_offset, sh4_scifb_size) | ||
289 | #define SCIF_FNS(name, scif_offset, scif_size) \ | 319 | #define SCIF_FNS(name, scif_offset, scif_size) \ |
290 | CPU_SCIF_FNS(name, scif_offset, scif_size) | 320 | CPU_SCIF_FNS(name, scif_offset, scif_size) |
291 | #else | 321 | #else |
@@ -320,7 +350,10 @@ | |||
320 | 350 | ||
321 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ | 351 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ |
322 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | 352 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ |
323 | defined(CONFIG_CPU_SUBTYPE_SH7721) | 353 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ |
354 | defined(CONFIG_ARCH_SH73A0) || \ | ||
355 | defined(CONFIG_ARCH_SH7367) || \ | ||
356 | defined(CONFIG_ARCH_SH7377) | ||
324 | 357 | ||
325 | SCIF_FNS(SCSMR, 0x00, 16) | 358 | SCIF_FNS(SCSMR, 0x00, 16) |
326 | SCIF_FNS(SCBRR, 0x04, 8) | 359 | SCIF_FNS(SCBRR, 0x04, 8) |
@@ -330,7 +363,21 @@ SCIF_FNS(SCFCR, 0x18, 16) | |||
330 | SCIF_FNS(SCFDR, 0x1c, 16) | 363 | SCIF_FNS(SCFDR, 0x1c, 16) |
331 | SCIF_FNS(SCxTDR, 0x20, 8) | 364 | SCIF_FNS(SCxTDR, 0x20, 8) |
332 | SCIF_FNS(SCxRDR, 0x24, 8) | 365 | SCIF_FNS(SCxRDR, 0x24, 8) |
333 | SCIF_FNS(SCLSR, 0x24, 16) | 366 | SCIF_FNS(SCLSR, 0x00, 0) |
367 | #elif defined(CONFIG_ARCH_SH7372) | ||
368 | SCIF_FNS(SCSMR, 0x00, 16) | ||
369 | SCIF_FNS(SCBRR, 0x04, 8) | ||
370 | SCIF_FNS(SCSCR, 0x08, 16) | ||
371 | SCIF_FNS(SCTDSR, 0x0c, 16) | ||
372 | SCIF_FNS(SCFER, 0x10, 16) | ||
373 | SCIF_FNS(SCxSR, 0x14, 16) | ||
374 | SCIF_FNS(SCFCR, 0x18, 16) | ||
375 | SCIF_FNS(SCFDR, 0x1c, 16) | ||
376 | SCIF_FNS(SCTFDR, 0x38, 16) | ||
377 | SCIF_FNS(SCRFDR, 0x3c, 16) | ||
378 | SCIx_FNS(SCxTDR, 0x20, 8, 0x40, 8) | ||
379 | SCIx_FNS(SCxRDR, 0x24, 8, 0x60, 8) | ||
380 | SCIF_FNS(SCLSR, 0x00, 0) | ||
334 | #elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\ | 381 | #elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\ |
335 | defined(CONFIG_CPU_SUBTYPE_SH7724) | 382 | defined(CONFIG_CPU_SUBTYPE_SH7724) |
336 | SCIx_FNS(SCSMR, 0x00, 16, 0x00, 16) | 383 | SCIx_FNS(SCSMR, 0x00, 16, 0x00, 16) |
@@ -431,35 +478,7 @@ static const struct __attribute__((packed)) { | |||
431 | static inline int sci_rxd_in(struct uart_port *port) | 478 | static inline int sci_rxd_in(struct uart_port *port) |
432 | { | 479 | { |
433 | if (port->mapbase == 0xfffffe80) | 480 | if (port->mapbase == 0xfffffe80) |
434 | return ctrl_inb(SCPDR)&0x01 ? 1 : 0; /* SCI */ | 481 | return __raw_readb(SCPDR)&0x01 ? 1 : 0; /* SCI */ |
435 | if (port->mapbase == 0xa4000150) | ||
436 | return ctrl_inb(SCPDR)&0x10 ? 1 : 0; /* SCIF */ | ||
437 | if (port->mapbase == 0xa4000140) | ||
438 | return ctrl_inb(SCPDR)&0x04 ? 1 : 0; /* IRDA */ | ||
439 | return 1; | ||
440 | } | ||
441 | #elif defined(CONFIG_CPU_SUBTYPE_SH7705) | ||
442 | static inline int sci_rxd_in(struct uart_port *port) | ||
443 | { | ||
444 | if (port->mapbase == SCIF0) | ||
445 | return ctrl_inb(SCPDR)&0x04 ? 1 : 0; /* IRDA */ | ||
446 | if (port->mapbase == SCIF2) | ||
447 | return ctrl_inb(SCPDR)&0x10 ? 1 : 0; /* SCIF */ | ||
448 | return 1; | ||
449 | } | ||
450 | #elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) | ||
451 | static inline int sci_rxd_in(struct uart_port *port) | ||
452 | { | ||
453 | return sci_in(port,SCxSR)&0x0010 ? 1 : 0; | ||
454 | } | ||
455 | #elif defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | ||
456 | defined(CONFIG_CPU_SUBTYPE_SH7721) | ||
457 | static inline int sci_rxd_in(struct uart_port *port) | ||
458 | { | ||
459 | if (port->mapbase == 0xa4430000) | ||
460 | return sci_in(port, SCxSR) & 0x0003 ? 1 : 0; | ||
461 | else if (port->mapbase == 0xa4438000) | ||
462 | return sci_in(port, SCxSR) & 0x0003 ? 1 : 0; | ||
463 | return 1; | 482 | return 1; |
464 | } | 483 | } |
465 | #elif defined(CONFIG_CPU_SUBTYPE_SH7750) || \ | 484 | #elif defined(CONFIG_CPU_SUBTYPE_SH7750) || \ |
@@ -471,198 +490,18 @@ static inline int sci_rxd_in(struct uart_port *port) | |||
471 | static inline int sci_rxd_in(struct uart_port *port) | 490 | static inline int sci_rxd_in(struct uart_port *port) |
472 | { | 491 | { |
473 | if (port->mapbase == 0xffe00000) | 492 | if (port->mapbase == 0xffe00000) |
474 | return ctrl_inb(SCSPTR1)&0x01 ? 1 : 0; /* SCI */ | 493 | return __raw_readb(SCSPTR1)&0x01 ? 1 : 0; /* SCI */ |
475 | if (port->mapbase == 0xffe80000) | ||
476 | return ctrl_inw(SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */ | ||
477 | return 1; | ||
478 | } | ||
479 | #elif defined(CONFIG_CPU_SUBTYPE_SH4_202) | ||
480 | static inline int sci_rxd_in(struct uart_port *port) | ||
481 | { | ||
482 | if (port->mapbase == 0xffe80000) | ||
483 | return ctrl_inw(SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */ | ||
484 | return 1; | ||
485 | } | ||
486 | #elif defined(CONFIG_CPU_SUBTYPE_SH7760) | ||
487 | static inline int sci_rxd_in(struct uart_port *port) | ||
488 | { | ||
489 | if (port->mapbase == 0xfe600000) | ||
490 | return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ | ||
491 | if (port->mapbase == 0xfe610000) | ||
492 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ | ||
493 | if (port->mapbase == 0xfe620000) | ||
494 | return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ | ||
495 | return 1; | ||
496 | } | ||
497 | #elif defined(CONFIG_CPU_SUBTYPE_SH7343) | ||
498 | static inline int sci_rxd_in(struct uart_port *port) | ||
499 | { | ||
500 | if (port->mapbase == 0xffe00000) | ||
501 | return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ | ||
502 | if (port->mapbase == 0xffe10000) | ||
503 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ | ||
504 | if (port->mapbase == 0xffe20000) | ||
505 | return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ | ||
506 | if (port->mapbase == 0xffe30000) | ||
507 | return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ | ||
508 | return 1; | ||
509 | } | ||
510 | #elif defined(CONFIG_CPU_SUBTYPE_SH7366) | ||
511 | static inline int sci_rxd_in(struct uart_port *port) | ||
512 | { | ||
513 | if (port->mapbase == 0xffe00000) | ||
514 | return ctrl_inb(SCPDR0) & 0x0001 ? 1 : 0; /* SCIF0 */ | ||
515 | return 1; | ||
516 | } | ||
517 | #elif defined(CONFIG_CPU_SUBTYPE_SH7722) | ||
518 | static inline int sci_rxd_in(struct uart_port *port) | ||
519 | { | ||
520 | if (port->mapbase == 0xffe00000) | ||
521 | return ctrl_inb(PSDR) & 0x02 ? 1 : 0; /* SCIF0 */ | ||
522 | if (port->mapbase == 0xffe10000) | ||
523 | return ctrl_inb(PADR) & 0x40 ? 1 : 0; /* SCIF1 */ | ||
524 | if (port->mapbase == 0xffe20000) | ||
525 | return ctrl_inb(PWDR) & 0x04 ? 1 : 0; /* SCIF2 */ | ||
526 | |||
527 | return 1; | 494 | return 1; |
528 | } | 495 | } |
529 | #elif defined(CONFIG_CPU_SUBTYPE_SH7723) | ||
530 | static inline int sci_rxd_in(struct uart_port *port) | ||
531 | { | ||
532 | if (port->mapbase == 0xffe00000) | ||
533 | return ctrl_inb(SCSPTR0) & 0x0008 ? 1 : 0; /* SCIF0 */ | ||
534 | if (port->mapbase == 0xffe10000) | ||
535 | return ctrl_inb(SCSPTR1) & 0x0020 ? 1 : 0; /* SCIF1 */ | ||
536 | if (port->mapbase == 0xffe20000) | ||
537 | return ctrl_inb(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF2 */ | ||
538 | if (port->mapbase == 0xa4e30000) | ||
539 | return ctrl_inb(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF3 */ | ||
540 | if (port->mapbase == 0xa4e40000) | ||
541 | return ctrl_inb(SCSPTR4) & 0x0001 ? 1 : 0; /* SCIF4 */ | ||
542 | if (port->mapbase == 0xa4e50000) | ||
543 | return ctrl_inb(SCSPTR5) & 0x0008 ? 1 : 0; /* SCIF5 */ | ||
544 | return 1; | ||
545 | } | ||
546 | #elif defined(CONFIG_CPU_SUBTYPE_SH7724) | ||
547 | # define SCFSR 0x0010 | ||
548 | # define SCASSR 0x0014 | ||
549 | static inline int sci_rxd_in(struct uart_port *port) | ||
550 | { | ||
551 | if (port->type == PORT_SCIF) | ||
552 | return ctrl_inw((port->mapbase + SCFSR)) & SCIF_BRK ? 1 : 0; | ||
553 | if (port->type == PORT_SCIFA) | ||
554 | return ctrl_inw((port->mapbase + SCASSR)) & SCIF_BRK ? 1 : 0; | ||
555 | return 1; | ||
556 | } | ||
557 | #elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103) | ||
558 | static inline int sci_rxd_in(struct uart_port *port) | ||
559 | { | ||
560 | return sci_in(port, SCSPTR)&0x0001 ? 1 : 0; /* SCIF */ | ||
561 | } | ||
562 | #elif defined(__H8300H__) || defined(__H8300S__) | 496 | #elif defined(__H8300H__) || defined(__H8300S__) |
563 | static inline int sci_rxd_in(struct uart_port *port) | 497 | static inline int sci_rxd_in(struct uart_port *port) |
564 | { | 498 | { |
565 | int ch = (port->mapbase - SMR0) >> 3; | 499 | int ch = (port->mapbase - SMR0) >> 3; |
566 | return (H8300_SCI_DR(ch) & h8300_sci_pins[ch].rx) ? 1 : 0; | 500 | return (H8300_SCI_DR(ch) & h8300_sci_pins[ch].rx) ? 1 : 0; |
567 | } | 501 | } |
568 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) | 502 | #else /* default case for non-SCI processors */ |
569 | static inline int sci_rxd_in(struct uart_port *port) | ||
570 | { | ||
571 | if (port->mapbase == 0xffe00000) | ||
572 | return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ | ||
573 | if (port->mapbase == 0xffe08000) | ||
574 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ | ||
575 | if (port->mapbase == 0xffe10000) | ||
576 | return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF/IRDA */ | ||
577 | |||
578 | return 1; | ||
579 | } | ||
580 | #elif defined(CONFIG_CPU_SUBTYPE_SH7770) | ||
581 | static inline int sci_rxd_in(struct uart_port *port) | ||
582 | { | ||
583 | if (port->mapbase == 0xff923000) | ||
584 | return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ | ||
585 | if (port->mapbase == 0xff924000) | ||
586 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ | ||
587 | if (port->mapbase == 0xff925000) | ||
588 | return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ | ||
589 | return 1; | ||
590 | } | ||
591 | #elif defined(CONFIG_CPU_SUBTYPE_SH7780) | ||
592 | static inline int sci_rxd_in(struct uart_port *port) | ||
593 | { | ||
594 | if (port->mapbase == 0xffe00000) | ||
595 | return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ | ||
596 | if (port->mapbase == 0xffe10000) | ||
597 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ | ||
598 | return 1; | ||
599 | } | ||
600 | #elif defined(CONFIG_CPU_SUBTYPE_SH7785) || \ | ||
601 | defined(CONFIG_CPU_SUBTYPE_SH7786) | ||
602 | static inline int sci_rxd_in(struct uart_port *port) | ||
603 | { | ||
604 | if (port->mapbase == 0xffea0000) | ||
605 | return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ | ||
606 | if (port->mapbase == 0xffeb0000) | ||
607 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ | ||
608 | if (port->mapbase == 0xffec0000) | ||
609 | return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ | ||
610 | if (port->mapbase == 0xffed0000) | ||
611 | return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ | ||
612 | if (port->mapbase == 0xffee0000) | ||
613 | return ctrl_inw(SCSPTR4) & 0x0001 ? 1 : 0; /* SCIF */ | ||
614 | if (port->mapbase == 0xffef0000) | ||
615 | return ctrl_inw(SCSPTR5) & 0x0001 ? 1 : 0; /* SCIF */ | ||
616 | return 1; | ||
617 | } | ||
618 | #elif defined(CONFIG_CPU_SUBTYPE_SH7201) || \ | ||
619 | defined(CONFIG_CPU_SUBTYPE_SH7203) || \ | ||
620 | defined(CONFIG_CPU_SUBTYPE_SH7206) || \ | ||
621 | defined(CONFIG_CPU_SUBTYPE_SH7263) | ||
622 | static inline int sci_rxd_in(struct uart_port *port) | ||
623 | { | ||
624 | if (port->mapbase == 0xfffe8000) | ||
625 | return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ | ||
626 | if (port->mapbase == 0xfffe8800) | ||
627 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ | ||
628 | if (port->mapbase == 0xfffe9000) | ||
629 | return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ | ||
630 | if (port->mapbase == 0xfffe9800) | ||
631 | return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ | ||
632 | #if defined(CONFIG_CPU_SUBTYPE_SH7201) | ||
633 | if (port->mapbase == 0xfffeA000) | ||
634 | return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ | ||
635 | if (port->mapbase == 0xfffeA800) | ||
636 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ | ||
637 | if (port->mapbase == 0xfffeB000) | ||
638 | return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ | ||
639 | if (port->mapbase == 0xfffeB800) | ||
640 | return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ | ||
641 | #endif | ||
642 | return 1; | ||
643 | } | ||
644 | #elif defined(CONFIG_CPU_SUBTYPE_SH7619) | ||
645 | static inline int sci_rxd_in(struct uart_port *port) | ||
646 | { | ||
647 | if (port->mapbase == 0xf8400000) | ||
648 | return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ | ||
649 | if (port->mapbase == 0xf8410000) | ||
650 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ | ||
651 | if (port->mapbase == 0xf8420000) | ||
652 | return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ | ||
653 | return 1; | ||
654 | } | ||
655 | #elif defined(CONFIG_CPU_SUBTYPE_SHX3) | ||
656 | static inline int sci_rxd_in(struct uart_port *port) | 503 | static inline int sci_rxd_in(struct uart_port *port) |
657 | { | 504 | { |
658 | if (port->mapbase == 0xffc30000) | ||
659 | return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ | ||
660 | if (port->mapbase == 0xffc40000) | ||
661 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ | ||
662 | if (port->mapbase == 0xffc50000) | ||
663 | return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ | ||
664 | if (port->mapbase == 0xffc60000) | ||
665 | return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ | ||
666 | return 1; | 505 | return 1; |
667 | } | 506 | } |
668 | #endif | 507 | #endif |
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c index d5276c012f78..cff9a306660f 100644 --- a/drivers/serial/sn_console.c +++ b/drivers/serial/sn_console.c | |||
@@ -469,9 +469,9 @@ sn_receive_chars(struct sn_cons_port *port, unsigned long flags) | |||
469 | return; | 469 | return; |
470 | } | 470 | } |
471 | 471 | ||
472 | if (port->sc_port.info) { | 472 | if (port->sc_port.state) { |
473 | /* The serial_core stuffs are initilized, use them */ | 473 | /* The serial_core stuffs are initialized, use them */ |
474 | tty = port->sc_port.info->port.tty; | 474 | tty = port->sc_port.state->port.tty; |
475 | } | 475 | } |
476 | else { | 476 | else { |
477 | /* Not registered yet - can't pass to tty layer. */ | 477 | /* Not registered yet - can't pass to tty layer. */ |
@@ -492,7 +492,7 @@ sn_receive_chars(struct sn_cons_port *port, unsigned long flags) | |||
492 | sysrq_requested = 0; | 492 | sysrq_requested = 0; |
493 | if (ch && time_before(jiffies, sysrq_timeout)) { | 493 | if (ch && time_before(jiffies, sysrq_timeout)) { |
494 | spin_unlock_irqrestore(&port->sc_port.lock, flags); | 494 | spin_unlock_irqrestore(&port->sc_port.lock, flags); |
495 | handle_sysrq(ch, NULL); | 495 | handle_sysrq(ch); |
496 | spin_lock_irqsave(&port->sc_port.lock, flags); | 496 | spin_lock_irqsave(&port->sc_port.lock, flags); |
497 | /* ignore actual sysrq command char */ | 497 | /* ignore actual sysrq command char */ |
498 | continue; | 498 | continue; |
@@ -550,12 +550,12 @@ static void sn_transmit_chars(struct sn_cons_port *port, int raw) | |||
550 | 550 | ||
551 | BUG_ON(!port->sc_is_asynch); | 551 | BUG_ON(!port->sc_is_asynch); |
552 | 552 | ||
553 | if (port->sc_port.info) { | 553 | if (port->sc_port.state) { |
554 | /* We're initilized, using serial core infrastructure */ | 554 | /* We're initialized, using serial core infrastructure */ |
555 | xmit = &port->sc_port.info->xmit; | 555 | xmit = &port->sc_port.state->xmit; |
556 | } else { | 556 | } else { |
557 | /* Probably sn_sal_switch_to_asynch has been run but serial core isn't | 557 | /* Probably sn_sal_switch_to_asynch has been run but serial core isn't |
558 | * initilized yet. Just return. Writes are going through | 558 | * initialized yet. Just return. Writes are going through |
559 | * sn_sal_console_write (due to register_console) at this time. | 559 | * sn_sal_console_write (due to register_console) at this time. |
560 | */ | 560 | */ |
561 | return; | 561 | return; |
@@ -927,7 +927,7 @@ sn_sal_console_write(struct console *co, const char *s, unsigned count) | |||
927 | /* We can't look at the xmit buffer if we're not registered with serial core | 927 | /* We can't look at the xmit buffer if we're not registered with serial core |
928 | * yet. So only do the fancy recovery after registering | 928 | * yet. So only do the fancy recovery after registering |
929 | */ | 929 | */ |
930 | if (!port->sc_port.info) { | 930 | if (!port->sc_port.state) { |
931 | /* Not yet registered with serial core - simple case */ | 931 | /* Not yet registered with serial core - simple case */ |
932 | puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count); | 932 | puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count); |
933 | return; | 933 | return; |
@@ -936,8 +936,8 @@ sn_sal_console_write(struct console *co, const char *s, unsigned count) | |||
936 | /* somebody really wants this output, might be an | 936 | /* somebody really wants this output, might be an |
937 | * oops, kdb, panic, etc. make sure they get it. */ | 937 | * oops, kdb, panic, etc. make sure they get it. */ |
938 | if (spin_is_locked(&port->sc_port.lock)) { | 938 | if (spin_is_locked(&port->sc_port.lock)) { |
939 | int lhead = port->sc_port.info->xmit.head; | 939 | int lhead = port->sc_port.state->xmit.head; |
940 | int ltail = port->sc_port.info->xmit.tail; | 940 | int ltail = port->sc_port.state->xmit.tail; |
941 | int counter, got_lock = 0; | 941 | int counter, got_lock = 0; |
942 | 942 | ||
943 | /* | 943 | /* |
@@ -962,13 +962,13 @@ sn_sal_console_write(struct console *co, const char *s, unsigned count) | |||
962 | break; | 962 | break; |
963 | } else { | 963 | } else { |
964 | /* still locked */ | 964 | /* still locked */ |
965 | if ((lhead != port->sc_port.info->xmit.head) | 965 | if ((lhead != port->sc_port.state->xmit.head) |
966 | || (ltail != | 966 | || (ltail != |
967 | port->sc_port.info->xmit.tail)) { | 967 | port->sc_port.state->xmit.tail)) { |
968 | lhead = | 968 | lhead = |
969 | port->sc_port.info->xmit.head; | 969 | port->sc_port.state->xmit.head; |
970 | ltail = | 970 | ltail = |
971 | port->sc_port.info->xmit.tail; | 971 | port->sc_port.state->xmit.tail; |
972 | counter = 0; | 972 | counter = 0; |
973 | } | 973 | } |
974 | } | 974 | } |
diff --git a/drivers/serial/suncore.c b/drivers/serial/suncore.c index a2d4a19550ab..6381a0282ee7 100644 --- a/drivers/serial/suncore.c +++ b/drivers/serial/suncore.c | |||
@@ -53,46 +53,53 @@ void sunserial_unregister_minors(struct uart_driver *drv, int count) | |||
53 | EXPORT_SYMBOL(sunserial_unregister_minors); | 53 | EXPORT_SYMBOL(sunserial_unregister_minors); |
54 | 54 | ||
55 | int sunserial_console_match(struct console *con, struct device_node *dp, | 55 | int sunserial_console_match(struct console *con, struct device_node *dp, |
56 | struct uart_driver *drv, int line) | 56 | struct uart_driver *drv, int line, bool ignore_line) |
57 | { | 57 | { |
58 | int off; | 58 | if (!con) |
59 | |||
60 | if (!con || of_console_device != dp) | ||
61 | return 0; | 59 | return 0; |
62 | 60 | ||
63 | off = 0; | 61 | drv->cons = con; |
64 | if (of_console_options && | ||
65 | *of_console_options == 'b') | ||
66 | off = 1; | ||
67 | 62 | ||
68 | if ((line & 1) != off) | 63 | if (of_console_device != dp) |
69 | return 0; | 64 | return 0; |
70 | 65 | ||
71 | con->index = line; | 66 | if (!ignore_line) { |
72 | drv->cons = con; | 67 | int off = 0; |
73 | add_preferred_console(con->name, line, NULL); | 68 | |
69 | if (of_console_options && | ||
70 | *of_console_options == 'b') | ||
71 | off = 1; | ||
74 | 72 | ||
73 | if ((line & 1) != off) | ||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | if (!console_set_on_cmdline) { | ||
78 | con->index = line; | ||
79 | add_preferred_console(con->name, line, NULL); | ||
80 | } | ||
75 | return 1; | 81 | return 1; |
76 | } | 82 | } |
77 | EXPORT_SYMBOL(sunserial_console_match); | 83 | EXPORT_SYMBOL(sunserial_console_match); |
78 | 84 | ||
79 | void | 85 | void sunserial_console_termios(struct console *con, struct device_node *uart_dp) |
80 | sunserial_console_termios(struct console *con) | ||
81 | { | 86 | { |
82 | struct device_node *dp; | 87 | const char *mode, *s; |
83 | const char *od, *mode, *s; | ||
84 | char mode_prop[] = "ttyX-mode"; | 88 | char mode_prop[] = "ttyX-mode"; |
85 | int baud, bits, stop, cflag; | 89 | int baud, bits, stop, cflag; |
86 | char parity; | 90 | char parity; |
87 | 91 | ||
88 | dp = of_find_node_by_path("/options"); | 92 | if (!strcmp(uart_dp->name, "rsc") || |
89 | od = of_get_property(dp, "output-device", NULL); | 93 | !strcmp(uart_dp->name, "rsc-console") || |
90 | if (!strcmp(od, "rsc")) { | 94 | !strcmp(uart_dp->name, "rsc-control")) { |
91 | mode = of_get_property(of_console_device, | 95 | mode = of_get_property(uart_dp, |
92 | "ssp-console-modes", NULL); | 96 | "ssp-console-modes", NULL); |
93 | if (!mode) | 97 | if (!mode) |
94 | mode = "115200,8,n,1,-"; | 98 | mode = "115200,8,n,1,-"; |
99 | } else if (!strcmp(uart_dp->name, "lom-console")) { | ||
100 | mode = "9600,8,n,1,-"; | ||
95 | } else { | 101 | } else { |
102 | struct device_node *dp; | ||
96 | char c; | 103 | char c; |
97 | 104 | ||
98 | c = 'a'; | 105 | c = 'a'; |
@@ -101,6 +108,7 @@ sunserial_console_termios(struct console *con) | |||
101 | 108 | ||
102 | mode_prop[3] = c; | 109 | mode_prop[3] = c; |
103 | 110 | ||
111 | dp = of_find_node_by_path("/options"); | ||
104 | mode = of_get_property(dp, mode_prop, NULL); | 112 | mode = of_get_property(dp, mode_prop, NULL); |
105 | if (!mode) | 113 | if (!mode) |
106 | mode = "9600,8,n,1,-"; | 114 | mode = "9600,8,n,1,-"; |
diff --git a/drivers/serial/suncore.h b/drivers/serial/suncore.h index 042668aa602e..db2057936c31 100644 --- a/drivers/serial/suncore.h +++ b/drivers/serial/suncore.h | |||
@@ -26,7 +26,8 @@ extern int sunserial_register_minors(struct uart_driver *, int); | |||
26 | extern void sunserial_unregister_minors(struct uart_driver *, int); | 26 | extern void sunserial_unregister_minors(struct uart_driver *, int); |
27 | 27 | ||
28 | extern int sunserial_console_match(struct console *, struct device_node *, | 28 | extern int sunserial_console_match(struct console *, struct device_node *, |
29 | struct uart_driver *, int); | 29 | struct uart_driver *, int, bool); |
30 | extern void sunserial_console_termios(struct console *); | 30 | extern void sunserial_console_termios(struct console *, |
31 | struct device_node *); | ||
31 | 32 | ||
32 | #endif /* !(_SERIAL_SUN_H) */ | 33 | #endif /* !(_SERIAL_SUN_H) */ |
diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c index 1df5325faab2..c9014868297d 100644 --- a/drivers/serial/sunhv.c +++ b/drivers/serial/sunhv.c | |||
@@ -184,8 +184,8 @@ static struct tty_struct *receive_chars(struct uart_port *port) | |||
184 | { | 184 | { |
185 | struct tty_struct *tty = NULL; | 185 | struct tty_struct *tty = NULL; |
186 | 186 | ||
187 | if (port->info != NULL) /* Unopened serial console */ | 187 | if (port->state != NULL) /* Unopened serial console */ |
188 | tty = port->info->port.tty; | 188 | tty = port->state->port.tty; |
189 | 189 | ||
190 | if (sunhv_ops->receive_chars(port, tty)) | 190 | if (sunhv_ops->receive_chars(port, tty)) |
191 | sun_do_break(); | 191 | sun_do_break(); |
@@ -197,10 +197,10 @@ static void transmit_chars(struct uart_port *port) | |||
197 | { | 197 | { |
198 | struct circ_buf *xmit; | 198 | struct circ_buf *xmit; |
199 | 199 | ||
200 | if (!port->info) | 200 | if (!port->state) |
201 | return; | 201 | return; |
202 | 202 | ||
203 | xmit = &port->info->xmit; | 203 | xmit = &port->state->xmit; |
204 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) | 204 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) |
205 | return; | 205 | return; |
206 | 206 | ||
@@ -519,13 +519,13 @@ static struct console sunhv_console = { | |||
519 | .data = &sunhv_reg, | 519 | .data = &sunhv_reg, |
520 | }; | 520 | }; |
521 | 521 | ||
522 | static int __devinit hv_probe(struct of_device *op, const struct of_device_id *match) | 522 | static int __devinit hv_probe(struct platform_device *op, const struct of_device_id *match) |
523 | { | 523 | { |
524 | struct uart_port *port; | 524 | struct uart_port *port; |
525 | unsigned long minor; | 525 | unsigned long minor; |
526 | int err; | 526 | int err; |
527 | 527 | ||
528 | if (op->irqs[0] == 0xffffffff) | 528 | if (op->archdata.irqs[0] == 0xffffffff) |
529 | return -ENODEV; | 529 | return -ENODEV; |
530 | 530 | ||
531 | port = kzalloc(sizeof(struct uart_port), GFP_KERNEL); | 531 | port = kzalloc(sizeof(struct uart_port), GFP_KERNEL); |
@@ -557,7 +557,7 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m | |||
557 | 557 | ||
558 | port->membase = (unsigned char __iomem *) __pa(port); | 558 | port->membase = (unsigned char __iomem *) __pa(port); |
559 | 559 | ||
560 | port->irq = op->irqs[0]; | 560 | port->irq = op->archdata.irqs[0]; |
561 | 561 | ||
562 | port->dev = &op->dev; | 562 | port->dev = &op->dev; |
563 | 563 | ||
@@ -565,8 +565,8 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m | |||
565 | if (err) | 565 | if (err) |
566 | goto out_free_con_read_page; | 566 | goto out_free_con_read_page; |
567 | 567 | ||
568 | sunserial_console_match(&sunhv_console, op->node, | 568 | sunserial_console_match(&sunhv_console, op->dev.of_node, |
569 | &sunhv_reg, port->line); | 569 | &sunhv_reg, port->line, false); |
570 | 570 | ||
571 | err = uart_add_one_port(&sunhv_reg, port); | 571 | err = uart_add_one_port(&sunhv_reg, port); |
572 | if (err) | 572 | if (err) |
@@ -598,7 +598,7 @@ out_free_port: | |||
598 | return err; | 598 | return err; |
599 | } | 599 | } |
600 | 600 | ||
601 | static int __devexit hv_remove(struct of_device *dev) | 601 | static int __devexit hv_remove(struct platform_device *dev) |
602 | { | 602 | { |
603 | struct uart_port *port = dev_get_drvdata(&dev->dev); | 603 | struct uart_port *port = dev_get_drvdata(&dev->dev); |
604 | 604 | ||
@@ -630,8 +630,11 @@ static const struct of_device_id hv_match[] = { | |||
630 | MODULE_DEVICE_TABLE(of, hv_match); | 630 | MODULE_DEVICE_TABLE(of, hv_match); |
631 | 631 | ||
632 | static struct of_platform_driver hv_driver = { | 632 | static struct of_platform_driver hv_driver = { |
633 | .name = "hv", | 633 | .driver = { |
634 | .match_table = hv_match, | 634 | .name = "hv", |
635 | .owner = THIS_MODULE, | ||
636 | .of_match_table = hv_match, | ||
637 | }, | ||
635 | .probe = hv_probe, | 638 | .probe = hv_probe, |
636 | .remove = __devexit_p(hv_remove), | 639 | .remove = __devexit_p(hv_remove), |
637 | }; | 640 | }; |
@@ -641,12 +644,12 @@ static int __init sunhv_init(void) | |||
641 | if (tlb_type != hypervisor) | 644 | if (tlb_type != hypervisor) |
642 | return -ENODEV; | 645 | return -ENODEV; |
643 | 646 | ||
644 | return of_register_driver(&hv_driver, &of_bus_type); | 647 | return of_register_platform_driver(&hv_driver); |
645 | } | 648 | } |
646 | 649 | ||
647 | static void __exit sunhv_exit(void) | 650 | static void __exit sunhv_exit(void) |
648 | { | 651 | { |
649 | of_unregister_driver(&hv_driver); | 652 | of_unregister_platform_driver(&hv_driver); |
650 | } | 653 | } |
651 | 654 | ||
652 | module_init(sunhv_init); | 655 | module_init(sunhv_init); |
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index 0355efe115d9..5b246b18f42f 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c | |||
@@ -117,8 +117,8 @@ receive_chars(struct uart_sunsab_port *up, | |||
117 | int count = 0; | 117 | int count = 0; |
118 | int i; | 118 | int i; |
119 | 119 | ||
120 | if (up->port.info != NULL) /* Unopened serial console */ | 120 | if (up->port.state != NULL) /* Unopened serial console */ |
121 | tty = up->port.info->port.tty; | 121 | tty = up->port.state->port.tty; |
122 | 122 | ||
123 | /* Read number of BYTES (Character + Status) available. */ | 123 | /* Read number of BYTES (Character + Status) available. */ |
124 | if (stat->sreg.isr0 & SAB82532_ISR0_RPF) { | 124 | if (stat->sreg.isr0 & SAB82532_ISR0_RPF) { |
@@ -229,7 +229,7 @@ static void sunsab_tx_idle(struct uart_sunsab_port *); | |||
229 | static void transmit_chars(struct uart_sunsab_port *up, | 229 | static void transmit_chars(struct uart_sunsab_port *up, |
230 | union sab82532_irq_status *stat) | 230 | union sab82532_irq_status *stat) |
231 | { | 231 | { |
232 | struct circ_buf *xmit = &up->port.info->xmit; | 232 | struct circ_buf *xmit = &up->port.state->xmit; |
233 | int i; | 233 | int i; |
234 | 234 | ||
235 | if (stat->sreg.isr1 & SAB82532_ISR1_ALLS) { | 235 | if (stat->sreg.isr1 & SAB82532_ISR1_ALLS) { |
@@ -297,7 +297,7 @@ static void check_status(struct uart_sunsab_port *up, | |||
297 | up->port.icount.dsr++; | 297 | up->port.icount.dsr++; |
298 | } | 298 | } |
299 | 299 | ||
300 | wake_up_interruptible(&up->port.info->delta_msr_wait); | 300 | wake_up_interruptible(&up->port.state->port.delta_msr_wait); |
301 | } | 301 | } |
302 | 302 | ||
303 | static irqreturn_t sunsab_interrupt(int irq, void *dev_id) | 303 | static irqreturn_t sunsab_interrupt(int irq, void *dev_id) |
@@ -429,7 +429,7 @@ static void sunsab_tx_idle(struct uart_sunsab_port *up) | |||
429 | static void sunsab_start_tx(struct uart_port *port) | 429 | static void sunsab_start_tx(struct uart_port *port) |
430 | { | 430 | { |
431 | struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; | 431 | struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; |
432 | struct circ_buf *xmit = &up->port.info->xmit; | 432 | struct circ_buf *xmit = &up->port.state->xmit; |
433 | int i; | 433 | int i; |
434 | 434 | ||
435 | up->interrupt_mask1 &= ~(SAB82532_IMR1_ALLS|SAB82532_IMR1_XPR); | 435 | up->interrupt_mask1 &= ~(SAB82532_IMR1_ALLS|SAB82532_IMR1_XPR); |
@@ -474,7 +474,7 @@ static void sunsab_stop_rx(struct uart_port *port) | |||
474 | { | 474 | { |
475 | struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; | 475 | struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; |
476 | 476 | ||
477 | up->interrupt_mask0 |= SAB82532_ISR0_TCD; | 477 | up->interrupt_mask0 |= SAB82532_IMR0_TCD; |
478 | writeb(up->interrupt_mask1, &up->regs->w.imr0); | 478 | writeb(up->interrupt_mask1, &up->regs->w.imr0); |
479 | } | 479 | } |
480 | 480 | ||
@@ -883,7 +883,7 @@ static int sunsab_console_setup(struct console *con, char *options) | |||
883 | printk("Console: ttyS%d (SAB82532)\n", | 883 | printk("Console: ttyS%d (SAB82532)\n", |
884 | (sunsab_reg.minor - 64) + con->index); | 884 | (sunsab_reg.minor - 64) + con->index); |
885 | 885 | ||
886 | sunserial_console_termios(con); | 886 | sunserial_console_termios(con, up->port.dev->of_node); |
887 | 887 | ||
888 | switch (con->cflag & CBAUD) { | 888 | switch (con->cflag & CBAUD) { |
889 | case B150: baud = 150; break; | 889 | case B150: baud = 150; break; |
@@ -954,7 +954,7 @@ static inline struct console *SUNSAB_CONSOLE(void) | |||
954 | #endif | 954 | #endif |
955 | 955 | ||
956 | static int __devinit sunsab_init_one(struct uart_sunsab_port *up, | 956 | static int __devinit sunsab_init_one(struct uart_sunsab_port *up, |
957 | struct of_device *op, | 957 | struct platform_device *op, |
958 | unsigned long offset, | 958 | unsigned long offset, |
959 | int line) | 959 | int line) |
960 | { | 960 | { |
@@ -969,7 +969,7 @@ static int __devinit sunsab_init_one(struct uart_sunsab_port *up, | |||
969 | return -ENOMEM; | 969 | return -ENOMEM; |
970 | up->regs = (union sab82532_async_regs __iomem *) up->port.membase; | 970 | up->regs = (union sab82532_async_regs __iomem *) up->port.membase; |
971 | 971 | ||
972 | up->port.irq = op->irqs[0]; | 972 | up->port.irq = op->archdata.irqs[0]; |
973 | 973 | ||
974 | up->port.fifosize = SAB82532_XMIT_FIFO_SIZE; | 974 | up->port.fifosize = SAB82532_XMIT_FIFO_SIZE; |
975 | up->port.iotype = UPIO_MEM; | 975 | up->port.iotype = UPIO_MEM; |
@@ -1006,7 +1006,7 @@ static int __devinit sunsab_init_one(struct uart_sunsab_port *up, | |||
1006 | return 0; | 1006 | return 0; |
1007 | } | 1007 | } |
1008 | 1008 | ||
1009 | static int __devinit sab_probe(struct of_device *op, const struct of_device_id *match) | 1009 | static int __devinit sab_probe(struct platform_device *op, const struct of_device_id *match) |
1010 | { | 1010 | { |
1011 | static int inst; | 1011 | static int inst; |
1012 | struct uart_sunsab_port *up; | 1012 | struct uart_sunsab_port *up; |
@@ -1026,11 +1026,13 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id * | |||
1026 | if (err) | 1026 | if (err) |
1027 | goto out1; | 1027 | goto out1; |
1028 | 1028 | ||
1029 | sunserial_console_match(SUNSAB_CONSOLE(), op->node, | 1029 | sunserial_console_match(SUNSAB_CONSOLE(), op->dev.of_node, |
1030 | &sunsab_reg, up[0].port.line); | 1030 | &sunsab_reg, up[0].port.line, |
1031 | false); | ||
1031 | 1032 | ||
1032 | sunserial_console_match(SUNSAB_CONSOLE(), op->node, | 1033 | sunserial_console_match(SUNSAB_CONSOLE(), op->dev.of_node, |
1033 | &sunsab_reg, up[1].port.line); | 1034 | &sunsab_reg, up[1].port.line, |
1035 | false); | ||
1034 | 1036 | ||
1035 | err = uart_add_one_port(&sunsab_reg, &up[0].port); | 1037 | err = uart_add_one_port(&sunsab_reg, &up[0].port); |
1036 | if (err) | 1038 | if (err) |
@@ -1060,7 +1062,7 @@ out: | |||
1060 | return err; | 1062 | return err; |
1061 | } | 1063 | } |
1062 | 1064 | ||
1063 | static int __devexit sab_remove(struct of_device *op) | 1065 | static int __devexit sab_remove(struct platform_device *op) |
1064 | { | 1066 | { |
1065 | struct uart_sunsab_port *up = dev_get_drvdata(&op->dev); | 1067 | struct uart_sunsab_port *up = dev_get_drvdata(&op->dev); |
1066 | 1068 | ||
@@ -1091,8 +1093,11 @@ static const struct of_device_id sab_match[] = { | |||
1091 | MODULE_DEVICE_TABLE(of, sab_match); | 1093 | MODULE_DEVICE_TABLE(of, sab_match); |
1092 | 1094 | ||
1093 | static struct of_platform_driver sab_driver = { | 1095 | static struct of_platform_driver sab_driver = { |
1094 | .name = "sab", | 1096 | .driver = { |
1095 | .match_table = sab_match, | 1097 | .name = "sab", |
1098 | .owner = THIS_MODULE, | ||
1099 | .of_match_table = sab_match, | ||
1100 | }, | ||
1096 | .probe = sab_probe, | 1101 | .probe = sab_probe, |
1097 | .remove = __devexit_p(sab_remove), | 1102 | .remove = __devexit_p(sab_remove), |
1098 | }; | 1103 | }; |
@@ -1116,7 +1121,6 @@ static int __init sunsab_init(void) | |||
1116 | if (!sunsab_ports) | 1121 | if (!sunsab_ports) |
1117 | return -ENOMEM; | 1122 | return -ENOMEM; |
1118 | 1123 | ||
1119 | sunsab_reg.cons = SUNSAB_CONSOLE(); | ||
1120 | err = sunserial_register_minors(&sunsab_reg, num_channels); | 1124 | err = sunserial_register_minors(&sunsab_reg, num_channels); |
1121 | if (err) { | 1125 | if (err) { |
1122 | kfree(sunsab_ports); | 1126 | kfree(sunsab_ports); |
@@ -1126,12 +1130,12 @@ static int __init sunsab_init(void) | |||
1126 | } | 1130 | } |
1127 | } | 1131 | } |
1128 | 1132 | ||
1129 | return of_register_driver(&sab_driver, &of_bus_type); | 1133 | return of_register_platform_driver(&sab_driver); |
1130 | } | 1134 | } |
1131 | 1135 | ||
1132 | static void __exit sunsab_exit(void) | 1136 | static void __exit sunsab_exit(void) |
1133 | { | 1137 | { |
1134 | of_unregister_driver(&sab_driver); | 1138 | of_unregister_platform_driver(&sab_driver); |
1135 | if (sunsab_reg.nr) { | 1139 | if (sunsab_reg.nr) { |
1136 | sunserial_unregister_minors(&sunsab_reg, sunsab_reg.nr); | 1140 | sunserial_unregister_minors(&sunsab_reg, sunsab_reg.nr); |
1137 | } | 1141 | } |
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index 47c6837850b1..551ebfe3ccbb 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/serial.h> | 29 | #include <linux/serial.h> |
30 | #include <linux/sysrq.h> | 30 | #include <linux/sysrq.h> |
31 | #include <linux/console.h> | 31 | #include <linux/console.h> |
32 | #include <linux/slab.h> | ||
32 | #ifdef CONFIG_SERIO | 33 | #ifdef CONFIG_SERIO |
33 | #include <linux/serio.h> | 34 | #include <linux/serio.h> |
34 | #endif | 35 | #endif |
@@ -311,7 +312,7 @@ static void sunsu_enable_ms(struct uart_port *port) | |||
311 | static struct tty_struct * | 312 | static struct tty_struct * |
312 | receive_chars(struct uart_sunsu_port *up, unsigned char *status) | 313 | receive_chars(struct uart_sunsu_port *up, unsigned char *status) |
313 | { | 314 | { |
314 | struct tty_struct *tty = up->port.info->port.tty; | 315 | struct tty_struct *tty = up->port.state->port.tty; |
315 | unsigned char ch, flag; | 316 | unsigned char ch, flag; |
316 | int max_count = 256; | 317 | int max_count = 256; |
317 | int saw_console_brk = 0; | 318 | int saw_console_brk = 0; |
@@ -389,7 +390,7 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status) | |||
389 | 390 | ||
390 | static void transmit_chars(struct uart_sunsu_port *up) | 391 | static void transmit_chars(struct uart_sunsu_port *up) |
391 | { | 392 | { |
392 | struct circ_buf *xmit = &up->port.info->xmit; | 393 | struct circ_buf *xmit = &up->port.state->xmit; |
393 | int count; | 394 | int count; |
394 | 395 | ||
395 | if (up->port.x_char) { | 396 | if (up->port.x_char) { |
@@ -441,7 +442,7 @@ static void check_modem_status(struct uart_sunsu_port *up) | |||
441 | if (status & UART_MSR_DCTS) | 442 | if (status & UART_MSR_DCTS) |
442 | uart_handle_cts_change(&up->port, status & UART_MSR_CTS); | 443 | uart_handle_cts_change(&up->port, status & UART_MSR_CTS); |
443 | 444 | ||
444 | wake_up_interruptible(&up->port.info->delta_msr_wait); | 445 | wake_up_interruptible(&up->port.state->port.delta_msr_wait); |
445 | } | 446 | } |
446 | 447 | ||
447 | static irqreturn_t sunsu_serial_interrupt(int irq, void *dev_id) | 448 | static irqreturn_t sunsu_serial_interrupt(int irq, void *dev_id) |
@@ -1199,7 +1200,7 @@ static int __devinit sunsu_kbd_ms_init(struct uart_sunsu_port *up) | |||
1199 | return -ENODEV; | 1200 | return -ENODEV; |
1200 | 1201 | ||
1201 | printk("%s: %s port at %llx, irq %u\n", | 1202 | printk("%s: %s port at %llx, irq %u\n", |
1202 | to_of_device(up->port.dev)->node->full_name, | 1203 | up->port.dev->of_node->full_name, |
1203 | (up->su_type == SU_PORT_KBD) ? "Keyboard" : "Mouse", | 1204 | (up->su_type == SU_PORT_KBD) ? "Keyboard" : "Mouse", |
1204 | (unsigned long long) up->port.mapbase, | 1205 | (unsigned long long) up->port.mapbase, |
1205 | up->port.irq); | 1206 | up->port.irq); |
@@ -1329,11 +1330,9 @@ static void sunsu_console_write(struct console *co, const char *s, | |||
1329 | */ | 1330 | */ |
1330 | static int __init sunsu_console_setup(struct console *co, char *options) | 1331 | static int __init sunsu_console_setup(struct console *co, char *options) |
1331 | { | 1332 | { |
1333 | static struct ktermios dummy; | ||
1334 | struct ktermios termios; | ||
1332 | struct uart_port *port; | 1335 | struct uart_port *port; |
1333 | int baud = 9600; | ||
1334 | int bits = 8; | ||
1335 | int parity = 'n'; | ||
1336 | int flow = 'n'; | ||
1337 | 1336 | ||
1338 | printk("Console: ttyS%d (SU)\n", | 1337 | printk("Console: ttyS%d (SU)\n", |
1339 | (sunsu_reg.minor - 64) + co->index); | 1338 | (sunsu_reg.minor - 64) + co->index); |
@@ -1352,10 +1351,15 @@ static int __init sunsu_console_setup(struct console *co, char *options) | |||
1352 | */ | 1351 | */ |
1353 | spin_lock_init(&port->lock); | 1352 | spin_lock_init(&port->lock); |
1354 | 1353 | ||
1355 | if (options) | 1354 | /* Get firmware console settings. */ |
1356 | uart_parse_options(options, &baud, &parity, &bits, &flow); | 1355 | sunserial_console_termios(co, port->dev->of_node); |
1357 | 1356 | ||
1358 | return uart_set_options(port, co, baud, parity, bits, flow); | 1357 | memset(&termios, 0, sizeof(struct ktermios)); |
1358 | termios.c_cflag = co->cflag; | ||
1359 | port->mctrl |= TIOCM_DTR; | ||
1360 | port->ops->set_termios(port, &termios, &dummy); | ||
1361 | |||
1362 | return 0; | ||
1359 | } | 1363 | } |
1360 | 1364 | ||
1361 | static struct console sunsu_console = { | 1365 | static struct console sunsu_console = { |
@@ -1402,13 +1406,14 @@ static enum su_type __devinit su_get_type(struct device_node *dp) | |||
1402 | return SU_PORT_PORT; | 1406 | return SU_PORT_PORT; |
1403 | } | 1407 | } |
1404 | 1408 | ||
1405 | static int __devinit su_probe(struct of_device *op, const struct of_device_id *match) | 1409 | static int __devinit su_probe(struct platform_device *op, const struct of_device_id *match) |
1406 | { | 1410 | { |
1407 | static int inst; | 1411 | static int inst; |
1408 | struct device_node *dp = op->node; | 1412 | struct device_node *dp = op->dev.of_node; |
1409 | struct uart_sunsu_port *up; | 1413 | struct uart_sunsu_port *up; |
1410 | struct resource *rp; | 1414 | struct resource *rp; |
1411 | enum su_type type; | 1415 | enum su_type type; |
1416 | bool ignore_line; | ||
1412 | int err; | 1417 | int err; |
1413 | 1418 | ||
1414 | type = su_get_type(dp); | 1419 | type = su_get_type(dp); |
@@ -1438,7 +1443,7 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m | |||
1438 | return -ENOMEM; | 1443 | return -ENOMEM; |
1439 | } | 1444 | } |
1440 | 1445 | ||
1441 | up->port.irq = op->irqs[0]; | 1446 | up->port.irq = op->archdata.irqs[0]; |
1442 | 1447 | ||
1443 | up->port.dev = &op->dev; | 1448 | up->port.dev = &op->dev; |
1444 | 1449 | ||
@@ -1449,8 +1454,10 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m | |||
1449 | if (up->su_type == SU_PORT_KBD || up->su_type == SU_PORT_MS) { | 1454 | if (up->su_type == SU_PORT_KBD || up->su_type == SU_PORT_MS) { |
1450 | err = sunsu_kbd_ms_init(up); | 1455 | err = sunsu_kbd_ms_init(up); |
1451 | if (err) { | 1456 | if (err) { |
1457 | of_iounmap(&op->resource[0], | ||
1458 | up->port.membase, up->reg_size); | ||
1452 | kfree(up); | 1459 | kfree(up); |
1453 | goto out_unmap; | 1460 | return err; |
1454 | } | 1461 | } |
1455 | dev_set_drvdata(&op->dev, up); | 1462 | dev_set_drvdata(&op->dev, up); |
1456 | 1463 | ||
@@ -1467,8 +1474,14 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m | |||
1467 | 1474 | ||
1468 | up->port.ops = &sunsu_pops; | 1475 | up->port.ops = &sunsu_pops; |
1469 | 1476 | ||
1477 | ignore_line = false; | ||
1478 | if (!strcmp(dp->name, "rsc-console") || | ||
1479 | !strcmp(dp->name, "lom-console")) | ||
1480 | ignore_line = true; | ||
1481 | |||
1470 | sunserial_console_match(SUNSU_CONSOLE(), dp, | 1482 | sunserial_console_match(SUNSU_CONSOLE(), dp, |
1471 | &sunsu_reg, up->port.line); | 1483 | &sunsu_reg, up->port.line, |
1484 | ignore_line); | ||
1472 | err = uart_add_one_port(&sunsu_reg, &up->port); | 1485 | err = uart_add_one_port(&sunsu_reg, &up->port); |
1473 | if (err) | 1486 | if (err) |
1474 | goto out_unmap; | 1487 | goto out_unmap; |
@@ -1484,23 +1497,28 @@ out_unmap: | |||
1484 | return err; | 1497 | return err; |
1485 | } | 1498 | } |
1486 | 1499 | ||
1487 | static int __devexit su_remove(struct of_device *op) | 1500 | static int __devexit su_remove(struct platform_device *op) |
1488 | { | 1501 | { |
1489 | struct uart_sunsu_port *up = dev_get_drvdata(&op->dev); | 1502 | struct uart_sunsu_port *up = dev_get_drvdata(&op->dev); |
1503 | bool kbdms = false; | ||
1490 | 1504 | ||
1491 | if (up->su_type == SU_PORT_MS || | 1505 | if (up->su_type == SU_PORT_MS || |
1492 | up->su_type == SU_PORT_KBD) { | 1506 | up->su_type == SU_PORT_KBD) |
1507 | kbdms = true; | ||
1508 | |||
1509 | if (kbdms) { | ||
1493 | #ifdef CONFIG_SERIO | 1510 | #ifdef CONFIG_SERIO |
1494 | serio_unregister_port(&up->serio); | 1511 | serio_unregister_port(&up->serio); |
1495 | #endif | 1512 | #endif |
1496 | kfree(up); | 1513 | } else if (up->port.type != PORT_UNKNOWN) |
1497 | } else if (up->port.type != PORT_UNKNOWN) { | ||
1498 | uart_remove_one_port(&sunsu_reg, &up->port); | 1514 | uart_remove_one_port(&sunsu_reg, &up->port); |
1499 | } | ||
1500 | 1515 | ||
1501 | if (up->port.membase) | 1516 | if (up->port.membase) |
1502 | of_iounmap(&op->resource[0], up->port.membase, up->reg_size); | 1517 | of_iounmap(&op->resource[0], up->port.membase, up->reg_size); |
1503 | 1518 | ||
1519 | if (kbdms) | ||
1520 | kfree(up); | ||
1521 | |||
1504 | dev_set_drvdata(&op->dev, NULL); | 1522 | dev_set_drvdata(&op->dev, NULL); |
1505 | 1523 | ||
1506 | return 0; | 1524 | return 0; |
@@ -1517,13 +1535,20 @@ static const struct of_device_id su_match[] = { | |||
1517 | .name = "serial", | 1535 | .name = "serial", |
1518 | .compatible = "su", | 1536 | .compatible = "su", |
1519 | }, | 1537 | }, |
1538 | { | ||
1539 | .type = "serial", | ||
1540 | .compatible = "su", | ||
1541 | }, | ||
1520 | {}, | 1542 | {}, |
1521 | }; | 1543 | }; |
1522 | MODULE_DEVICE_TABLE(of, su_match); | 1544 | MODULE_DEVICE_TABLE(of, su_match); |
1523 | 1545 | ||
1524 | static struct of_platform_driver su_driver = { | 1546 | static struct of_platform_driver su_driver = { |
1525 | .name = "su", | 1547 | .driver = { |
1526 | .match_table = su_match, | 1548 | .name = "su", |
1549 | .owner = THIS_MODULE, | ||
1550 | .of_match_table = su_match, | ||
1551 | }, | ||
1527 | .probe = su_probe, | 1552 | .probe = su_probe, |
1528 | .remove = __devexit_p(su_remove), | 1553 | .remove = __devexit_p(su_remove), |
1529 | }; | 1554 | }; |
@@ -1548,6 +1573,12 @@ static int __init sunsu_init(void) | |||
1548 | num_uart++; | 1573 | num_uart++; |
1549 | } | 1574 | } |
1550 | } | 1575 | } |
1576 | for_each_node_by_type(dp, "serial") { | ||
1577 | if (of_device_is_compatible(dp, "su")) { | ||
1578 | if (su_get_type(dp) == SU_PORT_PORT) | ||
1579 | num_uart++; | ||
1580 | } | ||
1581 | } | ||
1551 | 1582 | ||
1552 | if (num_uart) { | 1583 | if (num_uart) { |
1553 | err = sunserial_register_minors(&sunsu_reg, num_uart); | 1584 | err = sunserial_register_minors(&sunsu_reg, num_uart); |
@@ -1555,7 +1586,7 @@ static int __init sunsu_init(void) | |||
1555 | return err; | 1586 | return err; |
1556 | } | 1587 | } |
1557 | 1588 | ||
1558 | err = of_register_driver(&su_driver, &of_bus_type); | 1589 | err = of_register_platform_driver(&su_driver); |
1559 | if (err && num_uart) | 1590 | if (err && num_uart) |
1560 | sunserial_unregister_minors(&sunsu_reg, num_uart); | 1591 | sunserial_unregister_minors(&sunsu_reg, num_uart); |
1561 | 1592 | ||
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index e09d3cebb4fb..c1967ac1c07f 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c | |||
@@ -102,6 +102,8 @@ struct uart_sunzilog_port { | |||
102 | #endif | 102 | #endif |
103 | }; | 103 | }; |
104 | 104 | ||
105 | static void sunzilog_putchar(struct uart_port *port, int ch); | ||
106 | |||
105 | #define ZILOG_CHANNEL_FROM_PORT(PORT) ((struct zilog_channel __iomem *)((PORT)->membase)) | 107 | #define ZILOG_CHANNEL_FROM_PORT(PORT) ((struct zilog_channel __iomem *)((PORT)->membase)) |
106 | #define UART_ZILOG(PORT) ((struct uart_sunzilog_port *)(PORT)) | 108 | #define UART_ZILOG(PORT) ((struct uart_sunzilog_port *)(PORT)) |
107 | 109 | ||
@@ -328,9 +330,9 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up, | |||
328 | unsigned char ch, r1, flag; | 330 | unsigned char ch, r1, flag; |
329 | 331 | ||
330 | tty = NULL; | 332 | tty = NULL; |
331 | if (up->port.info != NULL && /* Unopened serial console */ | 333 | if (up->port.state != NULL && /* Unopened serial console */ |
332 | up->port.info->port.tty != NULL) /* Keyboard || mouse */ | 334 | up->port.state->port.tty != NULL) /* Keyboard || mouse */ |
333 | tty = up->port.info->port.tty; | 335 | tty = up->port.state->port.tty; |
334 | 336 | ||
335 | for (;;) { | 337 | for (;;) { |
336 | 338 | ||
@@ -451,7 +453,7 @@ static void sunzilog_status_handle(struct uart_sunzilog_port *up, | |||
451 | uart_handle_cts_change(&up->port, | 453 | uart_handle_cts_change(&up->port, |
452 | (status & CTS)); | 454 | (status & CTS)); |
453 | 455 | ||
454 | wake_up_interruptible(&up->port.info->delta_msr_wait); | 456 | wake_up_interruptible(&up->port.state->port.delta_msr_wait); |
455 | } | 457 | } |
456 | 458 | ||
457 | up->prev_status = status; | 459 | up->prev_status = status; |
@@ -501,9 +503,9 @@ static void sunzilog_transmit_chars(struct uart_sunzilog_port *up, | |||
501 | return; | 503 | return; |
502 | } | 504 | } |
503 | 505 | ||
504 | if (up->port.info == NULL) | 506 | if (up->port.state == NULL) |
505 | goto ack_tx_int; | 507 | goto ack_tx_int; |
506 | xmit = &up->port.info->xmit; | 508 | xmit = &up->port.state->xmit; |
507 | if (uart_circ_empty(xmit)) | 509 | if (uart_circ_empty(xmit)) |
508 | goto ack_tx_int; | 510 | goto ack_tx_int; |
509 | 511 | ||
@@ -705,7 +707,7 @@ static void sunzilog_start_tx(struct uart_port *port) | |||
705 | port->icount.tx++; | 707 | port->icount.tx++; |
706 | port->x_char = 0; | 708 | port->x_char = 0; |
707 | } else { | 709 | } else { |
708 | struct circ_buf *xmit = &port->info->xmit; | 710 | struct circ_buf *xmit = &port->state->xmit; |
709 | 711 | ||
710 | writeb(xmit->buf[xmit->tail], &channel->data); | 712 | writeb(xmit->buf[xmit->tail], &channel->data); |
711 | ZSDELAY(); | 713 | ZSDELAY(); |
@@ -996,6 +998,50 @@ static int sunzilog_verify_port(struct uart_port *port, struct serial_struct *se | |||
996 | return -EINVAL; | 998 | return -EINVAL; |
997 | } | 999 | } |
998 | 1000 | ||
1001 | #ifdef CONFIG_CONSOLE_POLL | ||
1002 | static int sunzilog_get_poll_char(struct uart_port *port) | ||
1003 | { | ||
1004 | unsigned char ch, r1; | ||
1005 | struct uart_sunzilog_port *up = (struct uart_sunzilog_port *) port; | ||
1006 | struct zilog_channel __iomem *channel | ||
1007 | = ZILOG_CHANNEL_FROM_PORT(&up->port); | ||
1008 | |||
1009 | |||
1010 | r1 = read_zsreg(channel, R1); | ||
1011 | if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR)) { | ||
1012 | writeb(ERR_RES, &channel->control); | ||
1013 | ZSDELAY(); | ||
1014 | ZS_WSYNC(channel); | ||
1015 | } | ||
1016 | |||
1017 | ch = readb(&channel->control); | ||
1018 | ZSDELAY(); | ||
1019 | |||
1020 | /* This funny hack depends upon BRK_ABRT not interfering | ||
1021 | * with the other bits we care about in R1. | ||
1022 | */ | ||
1023 | if (ch & BRK_ABRT) | ||
1024 | r1 |= BRK_ABRT; | ||
1025 | |||
1026 | if (!(ch & Rx_CH_AV)) | ||
1027 | return NO_POLL_CHAR; | ||
1028 | |||
1029 | ch = readb(&channel->data); | ||
1030 | ZSDELAY(); | ||
1031 | |||
1032 | ch &= up->parity_mask; | ||
1033 | return ch; | ||
1034 | } | ||
1035 | |||
1036 | static void sunzilog_put_poll_char(struct uart_port *port, | ||
1037 | unsigned char ch) | ||
1038 | { | ||
1039 | struct uart_sunzilog_port *up = (struct uart_sunzilog_port *)port; | ||
1040 | |||
1041 | sunzilog_putchar(&up->port, ch); | ||
1042 | } | ||
1043 | #endif /* CONFIG_CONSOLE_POLL */ | ||
1044 | |||
999 | static struct uart_ops sunzilog_pops = { | 1045 | static struct uart_ops sunzilog_pops = { |
1000 | .tx_empty = sunzilog_tx_empty, | 1046 | .tx_empty = sunzilog_tx_empty, |
1001 | .set_mctrl = sunzilog_set_mctrl, | 1047 | .set_mctrl = sunzilog_set_mctrl, |
@@ -1013,6 +1059,10 @@ static struct uart_ops sunzilog_pops = { | |||
1013 | .request_port = sunzilog_request_port, | 1059 | .request_port = sunzilog_request_port, |
1014 | .config_port = sunzilog_config_port, | 1060 | .config_port = sunzilog_config_port, |
1015 | .verify_port = sunzilog_verify_port, | 1061 | .verify_port = sunzilog_verify_port, |
1062 | #ifdef CONFIG_CONSOLE_POLL | ||
1063 | .poll_get_char = sunzilog_get_poll_char, | ||
1064 | .poll_put_char = sunzilog_put_poll_char, | ||
1065 | #endif | ||
1016 | }; | 1066 | }; |
1017 | 1067 | ||
1018 | static int uart_chip_count; | 1068 | static int uart_chip_count; |
@@ -1180,7 +1230,7 @@ static int __init sunzilog_console_setup(struct console *con, char *options) | |||
1180 | (sunzilog_reg.minor - 64) + con->index, con->index); | 1230 | (sunzilog_reg.minor - 64) + con->index, con->index); |
1181 | 1231 | ||
1182 | /* Get firmware console settings. */ | 1232 | /* Get firmware console settings. */ |
1183 | sunserial_console_termios(con); | 1233 | sunserial_console_termios(con, up->port.dev->of_node); |
1184 | 1234 | ||
1185 | /* Firmware console speed is limited to 150-->38400 baud so | 1235 | /* Firmware console speed is limited to 150-->38400 baud so |
1186 | * this hackish cflag thing is OK. | 1236 | * this hackish cflag thing is OK. |
@@ -1349,7 +1399,7 @@ static void __devinit sunzilog_init_hw(struct uart_sunzilog_port *up) | |||
1349 | 1399 | ||
1350 | static int zilog_irq = -1; | 1400 | static int zilog_irq = -1; |
1351 | 1401 | ||
1352 | static int __devinit zs_probe(struct of_device *op, const struct of_device_id *match) | 1402 | static int __devinit zs_probe(struct platform_device *op, const struct of_device_id *match) |
1353 | { | 1403 | { |
1354 | static int kbm_inst, uart_inst; | 1404 | static int kbm_inst, uart_inst; |
1355 | int inst; | 1405 | int inst; |
@@ -1358,7 +1408,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m | |||
1358 | int keyboard_mouse = 0; | 1408 | int keyboard_mouse = 0; |
1359 | int err; | 1409 | int err; |
1360 | 1410 | ||
1361 | if (of_find_property(op->node, "keyboard", NULL)) | 1411 | if (of_find_property(op->dev.of_node, "keyboard", NULL)) |
1362 | keyboard_mouse = 1; | 1412 | keyboard_mouse = 1; |
1363 | 1413 | ||
1364 | /* uarts must come before keyboards/mice */ | 1414 | /* uarts must come before keyboards/mice */ |
@@ -1376,7 +1426,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m | |||
1376 | rp = sunzilog_chip_regs[inst]; | 1426 | rp = sunzilog_chip_regs[inst]; |
1377 | 1427 | ||
1378 | if (zilog_irq == -1) | 1428 | if (zilog_irq == -1) |
1379 | zilog_irq = op->irqs[0]; | 1429 | zilog_irq = op->archdata.irqs[0]; |
1380 | 1430 | ||
1381 | up = &sunzilog_port_table[inst * 2]; | 1431 | up = &sunzilog_port_table[inst * 2]; |
1382 | 1432 | ||
@@ -1384,7 +1434,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m | |||
1384 | up[0].port.mapbase = op->resource[0].start + 0x00; | 1434 | up[0].port.mapbase = op->resource[0].start + 0x00; |
1385 | up[0].port.membase = (void __iomem *) &rp->channelA; | 1435 | up[0].port.membase = (void __iomem *) &rp->channelA; |
1386 | up[0].port.iotype = UPIO_MEM; | 1436 | up[0].port.iotype = UPIO_MEM; |
1387 | up[0].port.irq = op->irqs[0]; | 1437 | up[0].port.irq = op->archdata.irqs[0]; |
1388 | up[0].port.uartclk = ZS_CLOCK; | 1438 | up[0].port.uartclk = ZS_CLOCK; |
1389 | up[0].port.fifosize = 1; | 1439 | up[0].port.fifosize = 1; |
1390 | up[0].port.ops = &sunzilog_pops; | 1440 | up[0].port.ops = &sunzilog_pops; |
@@ -1401,7 +1451,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m | |||
1401 | up[1].port.mapbase = op->resource[0].start + 0x04; | 1451 | up[1].port.mapbase = op->resource[0].start + 0x04; |
1402 | up[1].port.membase = (void __iomem *) &rp->channelB; | 1452 | up[1].port.membase = (void __iomem *) &rp->channelB; |
1403 | up[1].port.iotype = UPIO_MEM; | 1453 | up[1].port.iotype = UPIO_MEM; |
1404 | up[1].port.irq = op->irqs[0]; | 1454 | up[1].port.irq = op->archdata.irqs[0]; |
1405 | up[1].port.uartclk = ZS_CLOCK; | 1455 | up[1].port.uartclk = ZS_CLOCK; |
1406 | up[1].port.fifosize = 1; | 1456 | up[1].port.fifosize = 1; |
1407 | up[1].port.ops = &sunzilog_pops; | 1457 | up[1].port.ops = &sunzilog_pops; |
@@ -1415,8 +1465,9 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m | |||
1415 | sunzilog_init_hw(&up[1]); | 1465 | sunzilog_init_hw(&up[1]); |
1416 | 1466 | ||
1417 | if (!keyboard_mouse) { | 1467 | if (!keyboard_mouse) { |
1418 | if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node, | 1468 | if (sunserial_console_match(SUNZILOG_CONSOLE(), op->dev.of_node, |
1419 | &sunzilog_reg, up[0].port.line)) | 1469 | &sunzilog_reg, up[0].port.line, |
1470 | false)) | ||
1420 | up->flags |= SUNZILOG_FLAG_IS_CONS; | 1471 | up->flags |= SUNZILOG_FLAG_IS_CONS; |
1421 | err = uart_add_one_port(&sunzilog_reg, &up[0].port); | 1472 | err = uart_add_one_port(&sunzilog_reg, &up[0].port); |
1422 | if (err) { | 1473 | if (err) { |
@@ -1424,8 +1475,9 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m | |||
1424 | rp, sizeof(struct zilog_layout)); | 1475 | rp, sizeof(struct zilog_layout)); |
1425 | return err; | 1476 | return err; |
1426 | } | 1477 | } |
1427 | if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node, | 1478 | if (sunserial_console_match(SUNZILOG_CONSOLE(), op->dev.of_node, |
1428 | &sunzilog_reg, up[1].port.line)) | 1479 | &sunzilog_reg, up[1].port.line, |
1480 | false)) | ||
1429 | up->flags |= SUNZILOG_FLAG_IS_CONS; | 1481 | up->flags |= SUNZILOG_FLAG_IS_CONS; |
1430 | err = uart_add_one_port(&sunzilog_reg, &up[1].port); | 1482 | err = uart_add_one_port(&sunzilog_reg, &up[1].port); |
1431 | if (err) { | 1483 | if (err) { |
@@ -1440,12 +1492,12 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m | |||
1440 | "is a %s\n", | 1492 | "is a %s\n", |
1441 | dev_name(&op->dev), | 1493 | dev_name(&op->dev), |
1442 | (unsigned long long) up[0].port.mapbase, | 1494 | (unsigned long long) up[0].port.mapbase, |
1443 | op->irqs[0], sunzilog_type(&up[0].port)); | 1495 | op->archdata.irqs[0], sunzilog_type(&up[0].port)); |
1444 | printk(KERN_INFO "%s: Mouse at MMIO 0x%llx (irq = %d) " | 1496 | printk(KERN_INFO "%s: Mouse at MMIO 0x%llx (irq = %d) " |
1445 | "is a %s\n", | 1497 | "is a %s\n", |
1446 | dev_name(&op->dev), | 1498 | dev_name(&op->dev), |
1447 | (unsigned long long) up[1].port.mapbase, | 1499 | (unsigned long long) up[1].port.mapbase, |
1448 | op->irqs[0], sunzilog_type(&up[1].port)); | 1500 | op->archdata.irqs[0], sunzilog_type(&up[1].port)); |
1449 | kbm_inst++; | 1501 | kbm_inst++; |
1450 | } | 1502 | } |
1451 | 1503 | ||
@@ -1464,7 +1516,7 @@ static void __devexit zs_remove_one(struct uart_sunzilog_port *up) | |||
1464 | uart_remove_one_port(&sunzilog_reg, &up->port); | 1516 | uart_remove_one_port(&sunzilog_reg, &up->port); |
1465 | } | 1517 | } |
1466 | 1518 | ||
1467 | static int __devexit zs_remove(struct of_device *op) | 1519 | static int __devexit zs_remove(struct platform_device *op) |
1468 | { | 1520 | { |
1469 | struct uart_sunzilog_port *up = dev_get_drvdata(&op->dev); | 1521 | struct uart_sunzilog_port *up = dev_get_drvdata(&op->dev); |
1470 | struct zilog_layout __iomem *regs; | 1522 | struct zilog_layout __iomem *regs; |
@@ -1489,8 +1541,11 @@ static const struct of_device_id zs_match[] = { | |||
1489 | MODULE_DEVICE_TABLE(of, zs_match); | 1541 | MODULE_DEVICE_TABLE(of, zs_match); |
1490 | 1542 | ||
1491 | static struct of_platform_driver zs_driver = { | 1543 | static struct of_platform_driver zs_driver = { |
1492 | .name = "zs", | 1544 | .driver = { |
1493 | .match_table = zs_match, | 1545 | .name = "zs", |
1546 | .owner = THIS_MODULE, | ||
1547 | .of_match_table = zs_match, | ||
1548 | }, | ||
1494 | .probe = zs_probe, | 1549 | .probe = zs_probe, |
1495 | .remove = __devexit_p(zs_remove), | 1550 | .remove = __devexit_p(zs_remove), |
1496 | }; | 1551 | }; |
@@ -1521,7 +1576,7 @@ static int __init sunzilog_init(void) | |||
1521 | goto out_free_tables; | 1576 | goto out_free_tables; |
1522 | } | 1577 | } |
1523 | 1578 | ||
1524 | err = of_register_driver(&zs_driver, &of_bus_type); | 1579 | err = of_register_platform_driver(&zs_driver); |
1525 | if (err) | 1580 | if (err) |
1526 | goto out_unregister_uart; | 1581 | goto out_unregister_uart; |
1527 | 1582 | ||
@@ -1549,7 +1604,7 @@ out: | |||
1549 | return err; | 1604 | return err; |
1550 | 1605 | ||
1551 | out_unregister_driver: | 1606 | out_unregister_driver: |
1552 | of_unregister_driver(&zs_driver); | 1607 | of_unregister_platform_driver(&zs_driver); |
1553 | 1608 | ||
1554 | out_unregister_uart: | 1609 | out_unregister_uart: |
1555 | if (num_sunzilog) { | 1610 | if (num_sunzilog) { |
@@ -1564,7 +1619,7 @@ out_free_tables: | |||
1564 | 1619 | ||
1565 | static void __exit sunzilog_exit(void) | 1620 | static void __exit sunzilog_exit(void) |
1566 | { | 1621 | { |
1567 | of_unregister_driver(&zs_driver); | 1622 | of_unregister_platform_driver(&zs_driver); |
1568 | 1623 | ||
1569 | if (zilog_irq != -1) { | 1624 | if (zilog_irq != -1) { |
1570 | struct uart_sunzilog_port *up = sunzilog_irq_chain; | 1625 | struct uart_sunzilog_port *up = sunzilog_irq_chain; |
diff --git a/drivers/serial/timbuart.c b/drivers/serial/timbuart.c index 063a313b755c..1f36b7eb7351 100644 --- a/drivers/serial/timbuart.c +++ b/drivers/serial/timbuart.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
28 | #include <linux/ioport.h> | 28 | #include <linux/ioport.h> |
29 | #include <linux/slab.h> | ||
29 | 30 | ||
30 | #include "timbuart.h" | 31 | #include "timbuart.h" |
31 | 32 | ||
@@ -67,17 +68,27 @@ static void timbuart_start_tx(struct uart_port *port) | |||
67 | tasklet_schedule(&uart->tasklet); | 68 | tasklet_schedule(&uart->tasklet); |
68 | } | 69 | } |
69 | 70 | ||
71 | static unsigned int timbuart_tx_empty(struct uart_port *port) | ||
72 | { | ||
73 | u32 isr = ioread32(port->membase + TIMBUART_ISR); | ||
74 | |||
75 | return (isr & TXBE) ? TIOCSER_TEMT : 0; | ||
76 | } | ||
77 | |||
70 | static void timbuart_flush_buffer(struct uart_port *port) | 78 | static void timbuart_flush_buffer(struct uart_port *port) |
71 | { | 79 | { |
72 | u8 ctl = ioread8(port->membase + TIMBUART_CTRL) | TIMBUART_CTRL_FLSHTX; | 80 | if (!timbuart_tx_empty(port)) { |
81 | u8 ctl = ioread8(port->membase + TIMBUART_CTRL) | | ||
82 | TIMBUART_CTRL_FLSHTX; | ||
73 | 83 | ||
74 | iowrite8(ctl, port->membase + TIMBUART_CTRL); | 84 | iowrite8(ctl, port->membase + TIMBUART_CTRL); |
75 | iowrite32(TXBF, port->membase + TIMBUART_ISR); | 85 | iowrite32(TXBF, port->membase + TIMBUART_ISR); |
86 | } | ||
76 | } | 87 | } |
77 | 88 | ||
78 | static void timbuart_rx_chars(struct uart_port *port) | 89 | static void timbuart_rx_chars(struct uart_port *port) |
79 | { | 90 | { |
80 | struct tty_struct *tty = port->info->port.tty; | 91 | struct tty_struct *tty = port->state->port.tty; |
81 | 92 | ||
82 | while (ioread32(port->membase + TIMBUART_ISR) & RXDP) { | 93 | while (ioread32(port->membase + TIMBUART_ISR) & RXDP) { |
83 | u8 ch = ioread8(port->membase + TIMBUART_RXFIFO); | 94 | u8 ch = ioread8(port->membase + TIMBUART_RXFIFO); |
@@ -86,7 +97,7 @@ static void timbuart_rx_chars(struct uart_port *port) | |||
86 | } | 97 | } |
87 | 98 | ||
88 | spin_unlock(&port->lock); | 99 | spin_unlock(&port->lock); |
89 | tty_flip_buffer_push(port->info->port.tty); | 100 | tty_flip_buffer_push(port->state->port.tty); |
90 | spin_lock(&port->lock); | 101 | spin_lock(&port->lock); |
91 | 102 | ||
92 | dev_dbg(port->dev, "%s - total read %d bytes\n", | 103 | dev_dbg(port->dev, "%s - total read %d bytes\n", |
@@ -95,7 +106,7 @@ static void timbuart_rx_chars(struct uart_port *port) | |||
95 | 106 | ||
96 | static void timbuart_tx_chars(struct uart_port *port) | 107 | static void timbuart_tx_chars(struct uart_port *port) |
97 | { | 108 | { |
98 | struct circ_buf *xmit = &port->info->xmit; | 109 | struct circ_buf *xmit = &port->state->xmit; |
99 | 110 | ||
100 | while (!(ioread32(port->membase + TIMBUART_ISR) & TXBF) && | 111 | while (!(ioread32(port->membase + TIMBUART_ISR) & TXBF) && |
101 | !uart_circ_empty(xmit)) { | 112 | !uart_circ_empty(xmit)) { |
@@ -118,7 +129,7 @@ static void timbuart_handle_tx_port(struct uart_port *port, u32 isr, u32 *ier) | |||
118 | { | 129 | { |
119 | struct timbuart_port *uart = | 130 | struct timbuart_port *uart = |
120 | container_of(port, struct timbuart_port, port); | 131 | container_of(port, struct timbuart_port, port); |
121 | struct circ_buf *xmit = &port->info->xmit; | 132 | struct circ_buf *xmit = &port->state->xmit; |
122 | 133 | ||
123 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) | 134 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) |
124 | return; | 135 | return; |
@@ -194,13 +205,6 @@ void timbuart_tasklet(unsigned long arg) | |||
194 | dev_dbg(uart->port.dev, "%s leaving\n", __func__); | 205 | dev_dbg(uart->port.dev, "%s leaving\n", __func__); |
195 | } | 206 | } |
196 | 207 | ||
197 | static unsigned int timbuart_tx_empty(struct uart_port *port) | ||
198 | { | ||
199 | u32 isr = ioread32(port->membase + TIMBUART_ISR); | ||
200 | |||
201 | return (isr & TXBE) ? TIOCSER_TEMT : 0; | ||
202 | } | ||
203 | |||
204 | static unsigned int timbuart_get_mctrl(struct uart_port *port) | 208 | static unsigned int timbuart_get_mctrl(struct uart_port *port) |
205 | { | 209 | { |
206 | u8 cts = ioread8(port->membase + TIMBUART_CTRL); | 210 | u8 cts = ioread8(port->membase + TIMBUART_CTRL); |
@@ -219,7 +223,7 @@ static void timbuart_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
219 | if (mctrl & TIOCM_RTS) | 223 | if (mctrl & TIOCM_RTS) |
220 | iowrite8(TIMBUART_CTRL_RTS, port->membase + TIMBUART_CTRL); | 224 | iowrite8(TIMBUART_CTRL_RTS, port->membase + TIMBUART_CTRL); |
221 | else | 225 | else |
222 | iowrite8(TIMBUART_CTRL_RTS, port->membase + TIMBUART_CTRL); | 226 | iowrite8(0, port->membase + TIMBUART_CTRL); |
223 | } | 227 | } |
224 | 228 | ||
225 | static void timbuart_mctrl_check(struct uart_port *port, u32 isr, u32 *ier) | 229 | static void timbuart_mctrl_check(struct uart_port *port, u32 isr, u32 *ier) |
@@ -231,7 +235,7 @@ static void timbuart_mctrl_check(struct uart_port *port, u32 isr, u32 *ier) | |||
231 | iowrite32(CTS_DELTA, port->membase + TIMBUART_ISR); | 235 | iowrite32(CTS_DELTA, port->membase + TIMBUART_ISR); |
232 | cts = timbuart_get_mctrl(port); | 236 | cts = timbuart_get_mctrl(port); |
233 | uart_handle_cts_change(port, cts & TIOCM_CTS); | 237 | uart_handle_cts_change(port, cts & TIOCM_CTS); |
234 | wake_up_interruptible(&port->info->delta_msr_wait); | 238 | wake_up_interruptible(&port->state->port.delta_msr_wait); |
235 | } | 239 | } |
236 | 240 | ||
237 | *ier |= CTS_DELTA; | 241 | *ier |= CTS_DELTA; |
@@ -419,9 +423,9 @@ static struct uart_driver timbuart_driver = { | |||
419 | .nr = 1 | 423 | .nr = 1 |
420 | }; | 424 | }; |
421 | 425 | ||
422 | static int timbuart_probe(struct platform_device *dev) | 426 | static int __devinit timbuart_probe(struct platform_device *dev) |
423 | { | 427 | { |
424 | int err; | 428 | int err, irq; |
425 | struct timbuart_port *uart; | 429 | struct timbuart_port *uart; |
426 | struct resource *iomem; | 430 | struct resource *iomem; |
427 | 431 | ||
@@ -453,11 +457,12 @@ static int timbuart_probe(struct platform_device *dev) | |||
453 | uart->port.mapbase = iomem->start; | 457 | uart->port.mapbase = iomem->start; |
454 | uart->port.membase = NULL; | 458 | uart->port.membase = NULL; |
455 | 459 | ||
456 | uart->port.irq = platform_get_irq(dev, 0); | 460 | irq = platform_get_irq(dev, 0); |
457 | if (uart->port.irq < 0) { | 461 | if (irq < 0) { |
458 | err = -EINVAL; | 462 | err = -EINVAL; |
459 | goto err_register; | 463 | goto err_register; |
460 | } | 464 | } |
465 | uart->port.irq = irq; | ||
461 | 466 | ||
462 | tasklet_init(&uart->tasklet, timbuart_tasklet, (unsigned long)uart); | 467 | tasklet_init(&uart->tasklet, timbuart_tasklet, (unsigned long)uart); |
463 | 468 | ||
@@ -484,7 +489,7 @@ err_mem: | |||
484 | return err; | 489 | return err; |
485 | } | 490 | } |
486 | 491 | ||
487 | static int timbuart_remove(struct platform_device *dev) | 492 | static int __devexit timbuart_remove(struct platform_device *dev) |
488 | { | 493 | { |
489 | struct timbuart_port *uart = platform_get_drvdata(dev); | 494 | struct timbuart_port *uart = platform_get_drvdata(dev); |
490 | 495 | ||
@@ -502,7 +507,7 @@ static struct platform_driver timbuart_platform_driver = { | |||
502 | .owner = THIS_MODULE, | 507 | .owner = THIS_MODULE, |
503 | }, | 508 | }, |
504 | .probe = timbuart_probe, | 509 | .probe = timbuart_probe, |
505 | .remove = timbuart_remove, | 510 | .remove = __devexit_p(timbuart_remove), |
506 | }; | 511 | }; |
507 | 512 | ||
508 | /*--------------------------------------------------------------------------*/ | 513 | /*--------------------------------------------------------------------------*/ |
diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c index 3317148a4b93..d2fce865b731 100644 --- a/drivers/serial/uartlite.c +++ b/drivers/serial/uartlite.c | |||
@@ -19,8 +19,9 @@ | |||
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include <asm/io.h> | 21 | #include <asm/io.h> |
22 | #if defined(CONFIG_OF) | 22 | #if defined(CONFIG_OF) && (defined(CONFIG_PPC32) || defined(CONFIG_MICROBLAZE)) |
23 | #include <linux/of.h> | 23 | #include <linux/of.h> |
24 | #include <linux/of_address.h> | ||
24 | #include <linux/of_device.h> | 25 | #include <linux/of_device.h> |
25 | #include <linux/of_platform.h> | 26 | #include <linux/of_platform.h> |
26 | 27 | ||
@@ -43,7 +44,7 @@ MODULE_DEVICE_TABLE(of, ulite_of_match); | |||
43 | * Register definitions | 44 | * Register definitions |
44 | * | 45 | * |
45 | * For register details see datasheet: | 46 | * For register details see datasheet: |
46 | * http://www.xilinx.com/bvdocs/ipcenter/data_sheet/opb_uartlite.pdf | 47 | * http://www.xilinx.com/support/documentation/ip_documentation/opb_uartlite.pdf |
47 | */ | 48 | */ |
48 | 49 | ||
49 | #define ULITE_RX 0x00 | 50 | #define ULITE_RX 0x00 |
@@ -75,7 +76,7 @@ static struct uart_port ulite_ports[ULITE_NR_UARTS]; | |||
75 | 76 | ||
76 | static int ulite_receive(struct uart_port *port, int stat) | 77 | static int ulite_receive(struct uart_port *port, int stat) |
77 | { | 78 | { |
78 | struct tty_struct *tty = port->info->port.tty; | 79 | struct tty_struct *tty = port->state->port.tty; |
79 | unsigned char ch = 0; | 80 | unsigned char ch = 0; |
80 | char flag = TTY_NORMAL; | 81 | char flag = TTY_NORMAL; |
81 | 82 | ||
@@ -86,7 +87,7 @@ static int ulite_receive(struct uart_port *port, int stat) | |||
86 | /* stats */ | 87 | /* stats */ |
87 | if (stat & ULITE_STATUS_RXVALID) { | 88 | if (stat & ULITE_STATUS_RXVALID) { |
88 | port->icount.rx++; | 89 | port->icount.rx++; |
89 | ch = readb(port->membase + ULITE_RX); | 90 | ch = ioread32be(port->membase + ULITE_RX); |
90 | 91 | ||
91 | if (stat & ULITE_STATUS_PARITY) | 92 | if (stat & ULITE_STATUS_PARITY) |
92 | port->icount.parity++; | 93 | port->icount.parity++; |
@@ -125,13 +126,13 @@ static int ulite_receive(struct uart_port *port, int stat) | |||
125 | 126 | ||
126 | static int ulite_transmit(struct uart_port *port, int stat) | 127 | static int ulite_transmit(struct uart_port *port, int stat) |
127 | { | 128 | { |
128 | struct circ_buf *xmit = &port->info->xmit; | 129 | struct circ_buf *xmit = &port->state->xmit; |
129 | 130 | ||
130 | if (stat & ULITE_STATUS_TXFULL) | 131 | if (stat & ULITE_STATUS_TXFULL) |
131 | return 0; | 132 | return 0; |
132 | 133 | ||
133 | if (port->x_char) { | 134 | if (port->x_char) { |
134 | writeb(port->x_char, port->membase + ULITE_TX); | 135 | iowrite32be(port->x_char, port->membase + ULITE_TX); |
135 | port->x_char = 0; | 136 | port->x_char = 0; |
136 | port->icount.tx++; | 137 | port->icount.tx++; |
137 | return 1; | 138 | return 1; |
@@ -140,7 +141,7 @@ static int ulite_transmit(struct uart_port *port, int stat) | |||
140 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) | 141 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) |
141 | return 0; | 142 | return 0; |
142 | 143 | ||
143 | writeb(xmit->buf[xmit->tail], port->membase + ULITE_TX); | 144 | iowrite32be(xmit->buf[xmit->tail], port->membase + ULITE_TX); |
144 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE-1); | 145 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE-1); |
145 | port->icount.tx++; | 146 | port->icount.tx++; |
146 | 147 | ||
@@ -154,17 +155,22 @@ static int ulite_transmit(struct uart_port *port, int stat) | |||
154 | static irqreturn_t ulite_isr(int irq, void *dev_id) | 155 | static irqreturn_t ulite_isr(int irq, void *dev_id) |
155 | { | 156 | { |
156 | struct uart_port *port = dev_id; | 157 | struct uart_port *port = dev_id; |
157 | int busy; | 158 | int busy, n = 0; |
158 | 159 | ||
159 | do { | 160 | do { |
160 | int stat = readb(port->membase + ULITE_STATUS); | 161 | int stat = ioread32be(port->membase + ULITE_STATUS); |
161 | busy = ulite_receive(port, stat); | 162 | busy = ulite_receive(port, stat); |
162 | busy |= ulite_transmit(port, stat); | 163 | busy |= ulite_transmit(port, stat); |
164 | n++; | ||
163 | } while (busy); | 165 | } while (busy); |
164 | 166 | ||
165 | tty_flip_buffer_push(port->info->port.tty); | 167 | /* work done? */ |
166 | 168 | if (n > 1) { | |
167 | return IRQ_HANDLED; | 169 | tty_flip_buffer_push(port->state->port.tty); |
170 | return IRQ_HANDLED; | ||
171 | } else { | ||
172 | return IRQ_NONE; | ||
173 | } | ||
168 | } | 174 | } |
169 | 175 | ||
170 | static unsigned int ulite_tx_empty(struct uart_port *port) | 176 | static unsigned int ulite_tx_empty(struct uart_port *port) |
@@ -173,7 +179,7 @@ static unsigned int ulite_tx_empty(struct uart_port *port) | |||
173 | unsigned int ret; | 179 | unsigned int ret; |
174 | 180 | ||
175 | spin_lock_irqsave(&port->lock, flags); | 181 | spin_lock_irqsave(&port->lock, flags); |
176 | ret = readb(port->membase + ULITE_STATUS); | 182 | ret = ioread32be(port->membase + ULITE_STATUS); |
177 | spin_unlock_irqrestore(&port->lock, flags); | 183 | spin_unlock_irqrestore(&port->lock, flags); |
178 | 184 | ||
179 | return ret & ULITE_STATUS_TXEMPTY ? TIOCSER_TEMT : 0; | 185 | return ret & ULITE_STATUS_TXEMPTY ? TIOCSER_TEMT : 0; |
@@ -196,7 +202,7 @@ static void ulite_stop_tx(struct uart_port *port) | |||
196 | 202 | ||
197 | static void ulite_start_tx(struct uart_port *port) | 203 | static void ulite_start_tx(struct uart_port *port) |
198 | { | 204 | { |
199 | ulite_transmit(port, readb(port->membase + ULITE_STATUS)); | 205 | ulite_transmit(port, ioread32be(port->membase + ULITE_STATUS)); |
200 | } | 206 | } |
201 | 207 | ||
202 | static void ulite_stop_rx(struct uart_port *port) | 208 | static void ulite_stop_rx(struct uart_port *port) |
@@ -221,21 +227,21 @@ static int ulite_startup(struct uart_port *port) | |||
221 | int ret; | 227 | int ret; |
222 | 228 | ||
223 | ret = request_irq(port->irq, ulite_isr, | 229 | ret = request_irq(port->irq, ulite_isr, |
224 | IRQF_DISABLED | IRQF_SAMPLE_RANDOM, "uartlite", port); | 230 | IRQF_SHARED | IRQF_SAMPLE_RANDOM, "uartlite", port); |
225 | if (ret) | 231 | if (ret) |
226 | return ret; | 232 | return ret; |
227 | 233 | ||
228 | writeb(ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX, | 234 | iowrite32be(ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX, |
229 | port->membase + ULITE_CONTROL); | 235 | port->membase + ULITE_CONTROL); |
230 | writeb(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL); | 236 | iowrite32be(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL); |
231 | 237 | ||
232 | return 0; | 238 | return 0; |
233 | } | 239 | } |
234 | 240 | ||
235 | static void ulite_shutdown(struct uart_port *port) | 241 | static void ulite_shutdown(struct uart_port *port) |
236 | { | 242 | { |
237 | writeb(0, port->membase + ULITE_CONTROL); | 243 | iowrite32be(0, port->membase + ULITE_CONTROL); |
238 | readb(port->membase + ULITE_CONTROL); /* dummy */ | 244 | ioread32be(port->membase + ULITE_CONTROL); /* dummy */ |
239 | free_irq(port->irq, port); | 245 | free_irq(port->irq, port); |
240 | } | 246 | } |
241 | 247 | ||
@@ -316,6 +322,26 @@ static int ulite_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
316 | return -EINVAL; | 322 | return -EINVAL; |
317 | } | 323 | } |
318 | 324 | ||
325 | #ifdef CONFIG_CONSOLE_POLL | ||
326 | static int ulite_get_poll_char(struct uart_port *port) | ||
327 | { | ||
328 | if (!(ioread32be(port->membase + ULITE_STATUS) | ||
329 | & ULITE_STATUS_RXVALID)) | ||
330 | return NO_POLL_CHAR; | ||
331 | |||
332 | return ioread32be(port->membase + ULITE_RX); | ||
333 | } | ||
334 | |||
335 | static void ulite_put_poll_char(struct uart_port *port, unsigned char ch) | ||
336 | { | ||
337 | while (ioread32be(port->membase + ULITE_STATUS) & ULITE_STATUS_TXFULL) | ||
338 | cpu_relax(); | ||
339 | |||
340 | /* write char to device */ | ||
341 | iowrite32be(ch, port->membase + ULITE_TX); | ||
342 | } | ||
343 | #endif | ||
344 | |||
319 | static struct uart_ops ulite_ops = { | 345 | static struct uart_ops ulite_ops = { |
320 | .tx_empty = ulite_tx_empty, | 346 | .tx_empty = ulite_tx_empty, |
321 | .set_mctrl = ulite_set_mctrl, | 347 | .set_mctrl = ulite_set_mctrl, |
@@ -332,7 +358,11 @@ static struct uart_ops ulite_ops = { | |||
332 | .release_port = ulite_release_port, | 358 | .release_port = ulite_release_port, |
333 | .request_port = ulite_request_port, | 359 | .request_port = ulite_request_port, |
334 | .config_port = ulite_config_port, | 360 | .config_port = ulite_config_port, |
335 | .verify_port = ulite_verify_port | 361 | .verify_port = ulite_verify_port, |
362 | #ifdef CONFIG_CONSOLE_POLL | ||
363 | .poll_get_char = ulite_get_poll_char, | ||
364 | .poll_put_char = ulite_put_poll_char, | ||
365 | #endif | ||
336 | }; | 366 | }; |
337 | 367 | ||
338 | /* --------------------------------------------------------------------- | 368 | /* --------------------------------------------------------------------- |
@@ -347,7 +377,7 @@ static void ulite_console_wait_tx(struct uart_port *port) | |||
347 | 377 | ||
348 | /* Spin waiting for TX fifo to have space available */ | 378 | /* Spin waiting for TX fifo to have space available */ |
349 | for (i = 0; i < 100000; i++) { | 379 | for (i = 0; i < 100000; i++) { |
350 | val = readb(port->membase + ULITE_STATUS); | 380 | val = ioread32be(port->membase + ULITE_STATUS); |
351 | if ((val & ULITE_STATUS_TXFULL) == 0) | 381 | if ((val & ULITE_STATUS_TXFULL) == 0) |
352 | break; | 382 | break; |
353 | cpu_relax(); | 383 | cpu_relax(); |
@@ -357,7 +387,7 @@ static void ulite_console_wait_tx(struct uart_port *port) | |||
357 | static void ulite_console_putchar(struct uart_port *port, int ch) | 387 | static void ulite_console_putchar(struct uart_port *port, int ch) |
358 | { | 388 | { |
359 | ulite_console_wait_tx(port); | 389 | ulite_console_wait_tx(port); |
360 | writeb(ch, port->membase + ULITE_TX); | 390 | iowrite32be(ch, port->membase + ULITE_TX); |
361 | } | 391 | } |
362 | 392 | ||
363 | static void ulite_console_write(struct console *co, const char *s, | 393 | static void ulite_console_write(struct console *co, const char *s, |
@@ -374,8 +404,8 @@ static void ulite_console_write(struct console *co, const char *s, | |||
374 | spin_lock_irqsave(&port->lock, flags); | 404 | spin_lock_irqsave(&port->lock, flags); |
375 | 405 | ||
376 | /* save and disable interrupt */ | 406 | /* save and disable interrupt */ |
377 | ier = readb(port->membase + ULITE_STATUS) & ULITE_STATUS_IE; | 407 | ier = ioread32be(port->membase + ULITE_STATUS) & ULITE_STATUS_IE; |
378 | writeb(0, port->membase + ULITE_CONTROL); | 408 | iowrite32be(0, port->membase + ULITE_CONTROL); |
379 | 409 | ||
380 | uart_console_write(port, s, count, ulite_console_putchar); | 410 | uart_console_write(port, s, count, ulite_console_putchar); |
381 | 411 | ||
@@ -383,13 +413,13 @@ static void ulite_console_write(struct console *co, const char *s, | |||
383 | 413 | ||
384 | /* restore interrupt state */ | 414 | /* restore interrupt state */ |
385 | if (ier) | 415 | if (ier) |
386 | writeb(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL); | 416 | iowrite32be(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL); |
387 | 417 | ||
388 | if (locked) | 418 | if (locked) |
389 | spin_unlock_irqrestore(&port->lock, flags); | 419 | spin_unlock_irqrestore(&port->lock, flags); |
390 | } | 420 | } |
391 | 421 | ||
392 | static int __init ulite_console_setup(struct console *co, char *options) | 422 | static int __devinit ulite_console_setup(struct console *co, char *options) |
393 | { | 423 | { |
394 | struct uart_port *port; | 424 | struct uart_port *port; |
395 | int baud = 9600; | 425 | int baud = 9600; |
@@ -576,9 +606,9 @@ static struct platform_driver ulite_platform_driver = { | |||
576 | /* --------------------------------------------------------------------- | 606 | /* --------------------------------------------------------------------- |
577 | * OF bus bindings | 607 | * OF bus bindings |
578 | */ | 608 | */ |
579 | #if defined(CONFIG_OF) | 609 | #if defined(CONFIG_OF) && (defined(CONFIG_PPC32) || defined(CONFIG_MICROBLAZE)) |
580 | static int __devinit | 610 | static int __devinit |
581 | ulite_of_probe(struct of_device *op, const struct of_device_id *match) | 611 | ulite_of_probe(struct platform_device *op, const struct of_device_id *match) |
582 | { | 612 | { |
583 | struct resource res; | 613 | struct resource res; |
584 | const unsigned int *id; | 614 | const unsigned int *id; |
@@ -586,32 +616,31 @@ ulite_of_probe(struct of_device *op, const struct of_device_id *match) | |||
586 | 616 | ||
587 | dev_dbg(&op->dev, "%s(%p, %p)\n", __func__, op, match); | 617 | dev_dbg(&op->dev, "%s(%p, %p)\n", __func__, op, match); |
588 | 618 | ||
589 | rc = of_address_to_resource(op->node, 0, &res); | 619 | rc = of_address_to_resource(op->dev.of_node, 0, &res); |
590 | if (rc) { | 620 | if (rc) { |
591 | dev_err(&op->dev, "invalid address\n"); | 621 | dev_err(&op->dev, "invalid address\n"); |
592 | return rc; | 622 | return rc; |
593 | } | 623 | } |
594 | 624 | ||
595 | irq = irq_of_parse_and_map(op->node, 0); | 625 | irq = irq_of_parse_and_map(op->dev.of_node, 0); |
596 | 626 | ||
597 | id = of_get_property(op->node, "port-number", NULL); | 627 | id = of_get_property(op->dev.of_node, "port-number", NULL); |
598 | 628 | ||
599 | return ulite_assign(&op->dev, id ? *id : -1, res.start+3, irq); | 629 | return ulite_assign(&op->dev, id ? *id : -1, res.start, irq); |
600 | } | 630 | } |
601 | 631 | ||
602 | static int __devexit ulite_of_remove(struct of_device *op) | 632 | static int __devexit ulite_of_remove(struct platform_device *op) |
603 | { | 633 | { |
604 | return ulite_release(&op->dev); | 634 | return ulite_release(&op->dev); |
605 | } | 635 | } |
606 | 636 | ||
607 | static struct of_platform_driver ulite_of_driver = { | 637 | static struct of_platform_driver ulite_of_driver = { |
608 | .owner = THIS_MODULE, | ||
609 | .name = "uartlite", | ||
610 | .match_table = ulite_of_match, | ||
611 | .probe = ulite_of_probe, | 638 | .probe = ulite_of_probe, |
612 | .remove = __devexit_p(ulite_of_remove), | 639 | .remove = __devexit_p(ulite_of_remove), |
613 | .driver = { | 640 | .driver = { |
614 | .name = "uartlite", | 641 | .name = "uartlite", |
642 | .owner = THIS_MODULE, | ||
643 | .of_match_table = ulite_of_match, | ||
615 | }, | 644 | }, |
616 | }; | 645 | }; |
617 | 646 | ||
@@ -626,11 +655,11 @@ static inline void __exit ulite_of_unregister(void) | |||
626 | { | 655 | { |
627 | of_unregister_platform_driver(&ulite_of_driver); | 656 | of_unregister_platform_driver(&ulite_of_driver); |
628 | } | 657 | } |
629 | #else /* CONFIG_OF */ | 658 | #else /* CONFIG_OF && (CONFIG_PPC32 || CONFIG_MICROBLAZE) */ |
630 | /* CONFIG_OF not enabled; do nothing helpers */ | 659 | /* Appropriate config not enabled; do nothing helpers */ |
631 | static inline int __init ulite_of_register(void) { return 0; } | 660 | static inline int __init ulite_of_register(void) { return 0; } |
632 | static inline void __exit ulite_of_unregister(void) { } | 661 | static inline void __exit ulite_of_unregister(void) { } |
633 | #endif /* CONFIG_OF */ | 662 | #endif /* CONFIG_OF && (CONFIG_PPC32 || CONFIG_MICROBLAZE) */ |
634 | 663 | ||
635 | /* --------------------------------------------------------------------- | 664 | /* --------------------------------------------------------------------- |
636 | * Module setup/teardown | 665 | * Module setup/teardown |
diff --git a/drivers/serial/ucc_uart.c b/drivers/serial/ucc_uart.c index e945e780b5c9..3f4848e2174a 100644 --- a/drivers/serial/ucc_uart.c +++ b/drivers/serial/ucc_uart.c | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/serial.h> | 22 | #include <linux/serial.h> |
23 | #include <linux/slab.h> | ||
23 | #include <linux/serial_core.h> | 24 | #include <linux/serial_core.h> |
24 | #include <linux/io.h> | 25 | #include <linux/io.h> |
25 | #include <linux/of_platform.h> | 26 | #include <linux/of_platform.h> |
@@ -313,7 +314,7 @@ static void qe_uart_stop_tx(struct uart_port *port) | |||
313 | * This function will attempt to stuff of all the characters from the | 314 | * This function will attempt to stuff of all the characters from the |
314 | * kernel's transmit buffer into TX BDs. | 315 | * kernel's transmit buffer into TX BDs. |
315 | * | 316 | * |
316 | * A return value of non-zero indicates that it sucessfully stuffed all | 317 | * A return value of non-zero indicates that it successfully stuffed all |
317 | * characters from the kernel buffer. | 318 | * characters from the kernel buffer. |
318 | * | 319 | * |
319 | * A return value of zero indicates that there are still characters in the | 320 | * A return value of zero indicates that there are still characters in the |
@@ -327,7 +328,7 @@ static int qe_uart_tx_pump(struct uart_qe_port *qe_port) | |||
327 | unsigned char *p; | 328 | unsigned char *p; |
328 | unsigned int count; | 329 | unsigned int count; |
329 | struct uart_port *port = &qe_port->port; | 330 | struct uart_port *port = &qe_port->port; |
330 | struct circ_buf *xmit = &port->info->xmit; | 331 | struct circ_buf *xmit = &port->state->xmit; |
331 | 332 | ||
332 | bdp = qe_port->rx_cur; | 333 | bdp = qe_port->rx_cur; |
333 | 334 | ||
@@ -466,7 +467,7 @@ static void qe_uart_int_rx(struct uart_qe_port *qe_port) | |||
466 | int i; | 467 | int i; |
467 | unsigned char ch, *cp; | 468 | unsigned char ch, *cp; |
468 | struct uart_port *port = &qe_port->port; | 469 | struct uart_port *port = &qe_port->port; |
469 | struct tty_struct *tty = port->info->port.tty; | 470 | struct tty_struct *tty = port->state->port.tty; |
470 | struct qe_bd *bdp; | 471 | struct qe_bd *bdp; |
471 | u16 status; | 472 | u16 status; |
472 | unsigned int flg; | 473 | unsigned int flg; |
@@ -1179,22 +1180,24 @@ static void uart_firmware_cont(const struct firmware *fw, void *context) | |||
1179 | 1180 | ||
1180 | if (firmware->header.length != fw->size) { | 1181 | if (firmware->header.length != fw->size) { |
1181 | dev_err(dev, "invalid firmware\n"); | 1182 | dev_err(dev, "invalid firmware\n"); |
1182 | return; | 1183 | goto out; |
1183 | } | 1184 | } |
1184 | 1185 | ||
1185 | ret = qe_upload_firmware(firmware); | 1186 | ret = qe_upload_firmware(firmware); |
1186 | if (ret) { | 1187 | if (ret) { |
1187 | dev_err(dev, "could not load firmware\n"); | 1188 | dev_err(dev, "could not load firmware\n"); |
1188 | return; | 1189 | goto out; |
1189 | } | 1190 | } |
1190 | 1191 | ||
1191 | firmware_loaded = 1; | 1192 | firmware_loaded = 1; |
1193 | out: | ||
1194 | release_firmware(fw); | ||
1192 | } | 1195 | } |
1193 | 1196 | ||
1194 | static int ucc_uart_probe(struct of_device *ofdev, | 1197 | static int ucc_uart_probe(struct platform_device *ofdev, |
1195 | const struct of_device_id *match) | 1198 | const struct of_device_id *match) |
1196 | { | 1199 | { |
1197 | struct device_node *np = ofdev->node; | 1200 | struct device_node *np = ofdev->dev.of_node; |
1198 | const unsigned int *iprop; /* Integer OF properties */ | 1201 | const unsigned int *iprop; /* Integer OF properties */ |
1199 | const char *sprop; /* String OF properties */ | 1202 | const char *sprop; /* String OF properties */ |
1200 | struct uart_qe_port *qe_port = NULL; | 1203 | struct uart_qe_port *qe_port = NULL; |
@@ -1247,7 +1250,7 @@ static int ucc_uart_probe(struct of_device *ofdev, | |||
1247 | */ | 1250 | */ |
1248 | ret = request_firmware_nowait(THIS_MODULE, | 1251 | ret = request_firmware_nowait(THIS_MODULE, |
1249 | FW_ACTION_HOTPLUG, filename, &ofdev->dev, | 1252 | FW_ACTION_HOTPLUG, filename, &ofdev->dev, |
1250 | &ofdev->dev, uart_firmware_cont); | 1253 | GFP_KERNEL, &ofdev->dev, uart_firmware_cont); |
1251 | if (ret) { | 1254 | if (ret) { |
1252 | dev_err(&ofdev->dev, | 1255 | dev_err(&ofdev->dev, |
1253 | "could not load firmware %s\n", | 1256 | "could not load firmware %s\n", |
@@ -1459,7 +1462,7 @@ static int ucc_uart_probe(struct of_device *ofdev, | |||
1459 | return 0; | 1462 | return 0; |
1460 | } | 1463 | } |
1461 | 1464 | ||
1462 | static int ucc_uart_remove(struct of_device *ofdev) | 1465 | static int ucc_uart_remove(struct platform_device *ofdev) |
1463 | { | 1466 | { |
1464 | struct uart_qe_port *qe_port = dev_get_drvdata(&ofdev->dev); | 1467 | struct uart_qe_port *qe_port = dev_get_drvdata(&ofdev->dev); |
1465 | 1468 | ||
@@ -1483,9 +1486,11 @@ static struct of_device_id ucc_uart_match[] = { | |||
1483 | MODULE_DEVICE_TABLE(of, ucc_uart_match); | 1486 | MODULE_DEVICE_TABLE(of, ucc_uart_match); |
1484 | 1487 | ||
1485 | static struct of_platform_driver ucc_uart_of_driver = { | 1488 | static struct of_platform_driver ucc_uart_of_driver = { |
1486 | .owner = THIS_MODULE, | 1489 | .driver = { |
1487 | .name = "ucc_uart", | 1490 | .name = "ucc_uart", |
1488 | .match_table = ucc_uart_match, | 1491 | .owner = THIS_MODULE, |
1492 | .of_match_table = ucc_uart_match, | ||
1493 | }, | ||
1489 | .probe = ucc_uart_probe, | 1494 | .probe = ucc_uart_probe, |
1490 | .remove = ucc_uart_remove, | 1495 | .remove = ucc_uart_remove, |
1491 | }; | 1496 | }; |
diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c index 0573f3b5175e..3beb6ab4fa68 100644 --- a/drivers/serial/vr41xx_siu.c +++ b/drivers/serial/vr41xx_siu.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for NEC VR4100 series Serial Interface Unit. | 2 | * Driver for NEC VR4100 series Serial Interface Unit. |
3 | * | 3 | * |
4 | * Copyright (C) 2004-2008 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | 4 | * Copyright (C) 2004-2008 Yoichi Yuasa <yuasa@linux-mips.org> |
5 | * | 5 | * |
6 | * Based on drivers/serial/8250.c, by Russell King. | 6 | * Based on drivers/serial/8250.c, by Russell King. |
7 | * | 7 | * |
@@ -318,7 +318,7 @@ static inline void receive_chars(struct uart_port *port, uint8_t *status) | |||
318 | char flag; | 318 | char flag; |
319 | int max_count = RX_MAX_COUNT; | 319 | int max_count = RX_MAX_COUNT; |
320 | 320 | ||
321 | tty = port->info->port.tty; | 321 | tty = port->state->port.tty; |
322 | lsr = *status; | 322 | lsr = *status; |
323 | 323 | ||
324 | do { | 324 | do { |
@@ -386,7 +386,7 @@ static inline void check_modem_status(struct uart_port *port) | |||
386 | if (msr & UART_MSR_DCTS) | 386 | if (msr & UART_MSR_DCTS) |
387 | uart_handle_cts_change(port, msr & UART_MSR_CTS); | 387 | uart_handle_cts_change(port, msr & UART_MSR_CTS); |
388 | 388 | ||
389 | wake_up_interruptible(&port->info->delta_msr_wait); | 389 | wake_up_interruptible(&port->state->port.delta_msr_wait); |
390 | } | 390 | } |
391 | 391 | ||
392 | static inline void transmit_chars(struct uart_port *port) | 392 | static inline void transmit_chars(struct uart_port *port) |
@@ -394,7 +394,7 @@ static inline void transmit_chars(struct uart_port *port) | |||
394 | struct circ_buf *xmit; | 394 | struct circ_buf *xmit; |
395 | int max_count = TX_MAX_COUNT; | 395 | int max_count = TX_MAX_COUNT; |
396 | 396 | ||
397 | xmit = &port->info->xmit; | 397 | xmit = &port->state->xmit; |
398 | 398 | ||
399 | if (port->x_char) { | 399 | if (port->x_char) { |
400 | siu_write(port, UART_TX, port->x_char); | 400 | siu_write(port, UART_TX, port->x_char); |
diff --git a/drivers/serial/vt8500_serial.c b/drivers/serial/vt8500_serial.c new file mode 100644 index 000000000000..322bf56c0d89 --- /dev/null +++ b/drivers/serial/vt8500_serial.c | |||
@@ -0,0 +1,648 @@ | |||
1 | /* | ||
2 | * drivers/serial/vt8500_serial.c | ||
3 | * | ||
4 | * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> | ||
5 | * | ||
6 | * Based on msm_serial.c, which is: | ||
7 | * Copyright (C) 2007 Google, Inc. | ||
8 | * Author: Robert Love <rlove@google.com> | ||
9 | * | ||
10 | * This software is licensed under the terms of the GNU General Public | ||
11 | * License version 2, as published by the Free Software Foundation, and | ||
12 | * may be copied, distributed, and modified under those terms. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | */ | ||
19 | |||
20 | #if defined(CONFIG_SERIAL_VT8500_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | ||
21 | # define SUPPORT_SYSRQ | ||
22 | #endif | ||
23 | |||
24 | #include <linux/hrtimer.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/io.h> | ||
28 | #include <linux/ioport.h> | ||
29 | #include <linux/irq.h> | ||
30 | #include <linux/init.h> | ||
31 | #include <linux/console.h> | ||
32 | #include <linux/tty.h> | ||
33 | #include <linux/tty_flip.h> | ||
34 | #include <linux/serial_core.h> | ||
35 | #include <linux/serial.h> | ||
36 | #include <linux/slab.h> | ||
37 | #include <linux/clk.h> | ||
38 | #include <linux/platform_device.h> | ||
39 | |||
40 | /* | ||
41 | * UART Register offsets | ||
42 | */ | ||
43 | |||
44 | #define VT8500_URTDR 0x0000 /* Transmit data */ | ||
45 | #define VT8500_URRDR 0x0004 /* Receive data */ | ||
46 | #define VT8500_URDIV 0x0008 /* Clock/Baud rate divisor */ | ||
47 | #define VT8500_URLCR 0x000C /* Line control */ | ||
48 | #define VT8500_URICR 0x0010 /* IrDA control */ | ||
49 | #define VT8500_URIER 0x0014 /* Interrupt enable */ | ||
50 | #define VT8500_URISR 0x0018 /* Interrupt status */ | ||
51 | #define VT8500_URUSR 0x001c /* UART status */ | ||
52 | #define VT8500_URFCR 0x0020 /* FIFO control */ | ||
53 | #define VT8500_URFIDX 0x0024 /* FIFO index */ | ||
54 | #define VT8500_URBKR 0x0028 /* Break signal count */ | ||
55 | #define VT8500_URTOD 0x002c /* Time out divisor */ | ||
56 | #define VT8500_TXFIFO 0x1000 /* Transmit FIFO (16x8) */ | ||
57 | #define VT8500_RXFIFO 0x1020 /* Receive FIFO (16x10) */ | ||
58 | |||
59 | /* | ||
60 | * Interrupt enable and status bits | ||
61 | */ | ||
62 | |||
63 | #define TXDE (1 << 0) /* Tx Data empty */ | ||
64 | #define RXDF (1 << 1) /* Rx Data full */ | ||
65 | #define TXFAE (1 << 2) /* Tx FIFO almost empty */ | ||
66 | #define TXFE (1 << 3) /* Tx FIFO empty */ | ||
67 | #define RXFAF (1 << 4) /* Rx FIFO almost full */ | ||
68 | #define RXFF (1 << 5) /* Rx FIFO full */ | ||
69 | #define TXUDR (1 << 6) /* Tx underrun */ | ||
70 | #define RXOVER (1 << 7) /* Rx overrun */ | ||
71 | #define PER (1 << 8) /* Parity error */ | ||
72 | #define FER (1 << 9) /* Frame error */ | ||
73 | #define TCTS (1 << 10) /* Toggle of CTS */ | ||
74 | #define RXTOUT (1 << 11) /* Rx timeout */ | ||
75 | #define BKDONE (1 << 12) /* Break signal done */ | ||
76 | #define ERR (1 << 13) /* AHB error response */ | ||
77 | |||
78 | #define RX_FIFO_INTS (RXFAF | RXFF | RXOVER | PER | FER | RXTOUT) | ||
79 | #define TX_FIFO_INTS (TXFAE | TXFE | TXUDR) | ||
80 | |||
81 | struct vt8500_port { | ||
82 | struct uart_port uart; | ||
83 | char name[16]; | ||
84 | struct clk *clk; | ||
85 | unsigned int ier; | ||
86 | }; | ||
87 | |||
88 | static inline void vt8500_write(struct uart_port *port, unsigned int val, | ||
89 | unsigned int off) | ||
90 | { | ||
91 | writel(val, port->membase + off); | ||
92 | } | ||
93 | |||
94 | static inline unsigned int vt8500_read(struct uart_port *port, unsigned int off) | ||
95 | { | ||
96 | return readl(port->membase + off); | ||
97 | } | ||
98 | |||
99 | static void vt8500_stop_tx(struct uart_port *port) | ||
100 | { | ||
101 | struct vt8500_port *vt8500_port = container_of(port, | ||
102 | struct vt8500_port, | ||
103 | uart); | ||
104 | |||
105 | vt8500_port->ier &= ~TX_FIFO_INTS; | ||
106 | vt8500_write(port, vt8500_port->ier, VT8500_URIER); | ||
107 | } | ||
108 | |||
109 | static void vt8500_stop_rx(struct uart_port *port) | ||
110 | { | ||
111 | struct vt8500_port *vt8500_port = container_of(port, | ||
112 | struct vt8500_port, | ||
113 | uart); | ||
114 | |||
115 | vt8500_port->ier &= ~RX_FIFO_INTS; | ||
116 | vt8500_write(port, vt8500_port->ier, VT8500_URIER); | ||
117 | } | ||
118 | |||
119 | static void vt8500_enable_ms(struct uart_port *port) | ||
120 | { | ||
121 | struct vt8500_port *vt8500_port = container_of(port, | ||
122 | struct vt8500_port, | ||
123 | uart); | ||
124 | |||
125 | vt8500_port->ier |= TCTS; | ||
126 | vt8500_write(port, vt8500_port->ier, VT8500_URIER); | ||
127 | } | ||
128 | |||
129 | static void handle_rx(struct uart_port *port) | ||
130 | { | ||
131 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | ||
132 | if (!tty) { | ||
133 | /* Discard data: no tty available */ | ||
134 | int count = (vt8500_read(port, VT8500_URFIDX) & 0x1f00) >> 8; | ||
135 | u16 ch; | ||
136 | while (count--) | ||
137 | ch = readw(port->membase + VT8500_RXFIFO); | ||
138 | return; | ||
139 | } | ||
140 | |||
141 | /* | ||
142 | * Handle overrun | ||
143 | */ | ||
144 | if ((vt8500_read(port, VT8500_URISR) & RXOVER)) { | ||
145 | port->icount.overrun++; | ||
146 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
147 | } | ||
148 | |||
149 | /* and now the main RX loop */ | ||
150 | while (vt8500_read(port, VT8500_URFIDX) & 0x1f00) { | ||
151 | unsigned int c; | ||
152 | char flag = TTY_NORMAL; | ||
153 | |||
154 | c = readw(port->membase + VT8500_RXFIFO) & 0x3ff; | ||
155 | |||
156 | /* Mask conditions we're ignorning. */ | ||
157 | c &= ~port->read_status_mask; | ||
158 | |||
159 | if (c & FER) { | ||
160 | port->icount.frame++; | ||
161 | flag = TTY_FRAME; | ||
162 | } else if (c & PER) { | ||
163 | port->icount.parity++; | ||
164 | flag = TTY_PARITY; | ||
165 | } | ||
166 | port->icount.rx++; | ||
167 | |||
168 | if (!uart_handle_sysrq_char(port, c)) | ||
169 | tty_insert_flip_char(tty, c, flag); | ||
170 | } | ||
171 | |||
172 | tty_flip_buffer_push(tty); | ||
173 | tty_kref_put(tty); | ||
174 | } | ||
175 | |||
176 | static void handle_tx(struct uart_port *port) | ||
177 | { | ||
178 | struct circ_buf *xmit = &port->state->xmit; | ||
179 | |||
180 | if (port->x_char) { | ||
181 | writeb(port->x_char, port->membase + VT8500_TXFIFO); | ||
182 | port->icount.tx++; | ||
183 | port->x_char = 0; | ||
184 | } | ||
185 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { | ||
186 | vt8500_stop_tx(port); | ||
187 | return; | ||
188 | } | ||
189 | |||
190 | while ((vt8500_read(port, VT8500_URFIDX) & 0x1f) < 16) { | ||
191 | if (uart_circ_empty(xmit)) | ||
192 | break; | ||
193 | |||
194 | writeb(xmit->buf[xmit->tail], port->membase + VT8500_TXFIFO); | ||
195 | |||
196 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
197 | port->icount.tx++; | ||
198 | } | ||
199 | |||
200 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
201 | uart_write_wakeup(port); | ||
202 | |||
203 | if (uart_circ_empty(xmit)) | ||
204 | vt8500_stop_tx(port); | ||
205 | } | ||
206 | |||
207 | static void vt8500_start_tx(struct uart_port *port) | ||
208 | { | ||
209 | struct vt8500_port *vt8500_port = container_of(port, | ||
210 | struct vt8500_port, | ||
211 | uart); | ||
212 | |||
213 | vt8500_port->ier &= ~TX_FIFO_INTS; | ||
214 | vt8500_write(port, vt8500_port->ier, VT8500_URIER); | ||
215 | handle_tx(port); | ||
216 | vt8500_port->ier |= TX_FIFO_INTS; | ||
217 | vt8500_write(port, vt8500_port->ier, VT8500_URIER); | ||
218 | } | ||
219 | |||
220 | static void handle_delta_cts(struct uart_port *port) | ||
221 | { | ||
222 | port->icount.cts++; | ||
223 | wake_up_interruptible(&port->state->port.delta_msr_wait); | ||
224 | } | ||
225 | |||
226 | static irqreturn_t vt8500_irq(int irq, void *dev_id) | ||
227 | { | ||
228 | struct uart_port *port = dev_id; | ||
229 | unsigned long isr; | ||
230 | |||
231 | spin_lock(&port->lock); | ||
232 | isr = vt8500_read(port, VT8500_URISR); | ||
233 | |||
234 | /* Acknowledge active status bits */ | ||
235 | vt8500_write(port, isr, VT8500_URISR); | ||
236 | |||
237 | if (isr & RX_FIFO_INTS) | ||
238 | handle_rx(port); | ||
239 | if (isr & TX_FIFO_INTS) | ||
240 | handle_tx(port); | ||
241 | if (isr & TCTS) | ||
242 | handle_delta_cts(port); | ||
243 | |||
244 | spin_unlock(&port->lock); | ||
245 | |||
246 | return IRQ_HANDLED; | ||
247 | } | ||
248 | |||
249 | static unsigned int vt8500_tx_empty(struct uart_port *port) | ||
250 | { | ||
251 | return (vt8500_read(port, VT8500_URFIDX) & 0x1f) < 16 ? | ||
252 | TIOCSER_TEMT : 0; | ||
253 | } | ||
254 | |||
255 | static unsigned int vt8500_get_mctrl(struct uart_port *port) | ||
256 | { | ||
257 | unsigned int usr; | ||
258 | |||
259 | usr = vt8500_read(port, VT8500_URUSR); | ||
260 | if (usr & (1 << 4)) | ||
261 | return TIOCM_CTS; | ||
262 | else | ||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | static void vt8500_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
267 | { | ||
268 | } | ||
269 | |||
270 | static void vt8500_break_ctl(struct uart_port *port, int break_ctl) | ||
271 | { | ||
272 | if (break_ctl) | ||
273 | vt8500_write(port, vt8500_read(port, VT8500_URLCR) | (1 << 9), | ||
274 | VT8500_URLCR); | ||
275 | } | ||
276 | |||
277 | static int vt8500_set_baud_rate(struct uart_port *port, unsigned int baud) | ||
278 | { | ||
279 | unsigned long div; | ||
280 | unsigned int loops = 1000; | ||
281 | |||
282 | div = vt8500_read(port, VT8500_URDIV) & ~(0x3ff); | ||
283 | |||
284 | if (unlikely((baud < 900) || (baud > 921600))) | ||
285 | div |= 7; | ||
286 | else | ||
287 | div |= (921600 / baud) - 1; | ||
288 | |||
289 | while ((vt8500_read(port, VT8500_URUSR) & (1 << 5)) && --loops) | ||
290 | cpu_relax(); | ||
291 | vt8500_write(port, div, VT8500_URDIV); | ||
292 | |||
293 | return baud; | ||
294 | } | ||
295 | |||
296 | static int vt8500_startup(struct uart_port *port) | ||
297 | { | ||
298 | struct vt8500_port *vt8500_port = | ||
299 | container_of(port, struct vt8500_port, uart); | ||
300 | int ret; | ||
301 | |||
302 | snprintf(vt8500_port->name, sizeof(vt8500_port->name), | ||
303 | "vt8500_serial%d", port->line); | ||
304 | |||
305 | ret = request_irq(port->irq, vt8500_irq, IRQF_TRIGGER_HIGH, | ||
306 | vt8500_port->name, port); | ||
307 | if (unlikely(ret)) | ||
308 | return ret; | ||
309 | |||
310 | vt8500_write(port, 0x03, VT8500_URLCR); /* enable TX & RX */ | ||
311 | |||
312 | return 0; | ||
313 | } | ||
314 | |||
315 | static void vt8500_shutdown(struct uart_port *port) | ||
316 | { | ||
317 | struct vt8500_port *vt8500_port = | ||
318 | container_of(port, struct vt8500_port, uart); | ||
319 | |||
320 | vt8500_port->ier = 0; | ||
321 | |||
322 | /* disable interrupts and FIFOs */ | ||
323 | vt8500_write(&vt8500_port->uart, 0, VT8500_URIER); | ||
324 | vt8500_write(&vt8500_port->uart, 0x880, VT8500_URFCR); | ||
325 | free_irq(port->irq, port); | ||
326 | } | ||
327 | |||
328 | static void vt8500_set_termios(struct uart_port *port, | ||
329 | struct ktermios *termios, | ||
330 | struct ktermios *old) | ||
331 | { | ||
332 | struct vt8500_port *vt8500_port = | ||
333 | container_of(port, struct vt8500_port, uart); | ||
334 | unsigned long flags; | ||
335 | unsigned int baud, lcr; | ||
336 | unsigned int loops = 1000; | ||
337 | |||
338 | spin_lock_irqsave(&port->lock, flags); | ||
339 | |||
340 | /* calculate and set baud rate */ | ||
341 | baud = uart_get_baud_rate(port, termios, old, 900, 921600); | ||
342 | baud = vt8500_set_baud_rate(port, baud); | ||
343 | if (tty_termios_baud_rate(termios)) | ||
344 | tty_termios_encode_baud_rate(termios, baud, baud); | ||
345 | |||
346 | /* calculate parity */ | ||
347 | lcr = vt8500_read(&vt8500_port->uart, VT8500_URLCR); | ||
348 | lcr &= ~((1 << 5) | (1 << 4)); | ||
349 | if (termios->c_cflag & PARENB) { | ||
350 | lcr |= (1 << 4); | ||
351 | termios->c_cflag &= ~CMSPAR; | ||
352 | if (termios->c_cflag & PARODD) | ||
353 | lcr |= (1 << 5); | ||
354 | } | ||
355 | |||
356 | /* calculate bits per char */ | ||
357 | lcr &= ~(1 << 2); | ||
358 | switch (termios->c_cflag & CSIZE) { | ||
359 | case CS7: | ||
360 | break; | ||
361 | case CS8: | ||
362 | default: | ||
363 | lcr |= (1 << 2); | ||
364 | termios->c_cflag &= ~CSIZE; | ||
365 | termios->c_cflag |= CS8; | ||
366 | break; | ||
367 | } | ||
368 | |||
369 | /* calculate stop bits */ | ||
370 | lcr &= ~(1 << 3); | ||
371 | if (termios->c_cflag & CSTOPB) | ||
372 | lcr |= (1 << 3); | ||
373 | |||
374 | /* set parity, bits per char, and stop bit */ | ||
375 | vt8500_write(&vt8500_port->uart, lcr, VT8500_URLCR); | ||
376 | |||
377 | /* Configure status bits to ignore based on termio flags. */ | ||
378 | port->read_status_mask = 0; | ||
379 | if (termios->c_iflag & IGNPAR) | ||
380 | port->read_status_mask = FER | PER; | ||
381 | |||
382 | uart_update_timeout(port, termios->c_cflag, baud); | ||
383 | |||
384 | /* Reset FIFOs */ | ||
385 | vt8500_write(&vt8500_port->uart, 0x88c, VT8500_URFCR); | ||
386 | while ((vt8500_read(&vt8500_port->uart, VT8500_URFCR) & 0xc) | ||
387 | && --loops) | ||
388 | cpu_relax(); | ||
389 | |||
390 | /* Every possible FIFO-related interrupt */ | ||
391 | vt8500_port->ier = RX_FIFO_INTS | TX_FIFO_INTS; | ||
392 | |||
393 | /* | ||
394 | * CTS flow control | ||
395 | */ | ||
396 | if (UART_ENABLE_MS(&vt8500_port->uart, termios->c_cflag)) | ||
397 | vt8500_port->ier |= TCTS; | ||
398 | |||
399 | vt8500_write(&vt8500_port->uart, 0x881, VT8500_URFCR); | ||
400 | vt8500_write(&vt8500_port->uart, vt8500_port->ier, VT8500_URIER); | ||
401 | |||
402 | spin_unlock_irqrestore(&port->lock, flags); | ||
403 | } | ||
404 | |||
405 | static const char *vt8500_type(struct uart_port *port) | ||
406 | { | ||
407 | struct vt8500_port *vt8500_port = | ||
408 | container_of(port, struct vt8500_port, uart); | ||
409 | return vt8500_port->name; | ||
410 | } | ||
411 | |||
412 | static void vt8500_release_port(struct uart_port *port) | ||
413 | { | ||
414 | } | ||
415 | |||
416 | static int vt8500_request_port(struct uart_port *port) | ||
417 | { | ||
418 | return 0; | ||
419 | } | ||
420 | |||
421 | static void vt8500_config_port(struct uart_port *port, int flags) | ||
422 | { | ||
423 | port->type = PORT_VT8500; | ||
424 | } | ||
425 | |||
426 | static int vt8500_verify_port(struct uart_port *port, | ||
427 | struct serial_struct *ser) | ||
428 | { | ||
429 | if (unlikely(ser->type != PORT_UNKNOWN && ser->type != PORT_VT8500)) | ||
430 | return -EINVAL; | ||
431 | if (unlikely(port->irq != ser->irq)) | ||
432 | return -EINVAL; | ||
433 | return 0; | ||
434 | } | ||
435 | |||
436 | static struct vt8500_port *vt8500_uart_ports[4]; | ||
437 | static struct uart_driver vt8500_uart_driver; | ||
438 | |||
439 | #ifdef CONFIG_SERIAL_VT8500_CONSOLE | ||
440 | |||
441 | static inline void wait_for_xmitr(struct uart_port *port) | ||
442 | { | ||
443 | unsigned int status, tmout = 10000; | ||
444 | |||
445 | /* Wait up to 10ms for the character(s) to be sent. */ | ||
446 | do { | ||
447 | status = vt8500_read(port, VT8500_URFIDX); | ||
448 | |||
449 | if (--tmout == 0) | ||
450 | break; | ||
451 | udelay(1); | ||
452 | } while (status & 0x10); | ||
453 | } | ||
454 | |||
455 | static void vt8500_console_putchar(struct uart_port *port, int c) | ||
456 | { | ||
457 | wait_for_xmitr(port); | ||
458 | writeb(c, port->membase + VT8500_TXFIFO); | ||
459 | } | ||
460 | |||
461 | static void vt8500_console_write(struct console *co, const char *s, | ||
462 | unsigned int count) | ||
463 | { | ||
464 | struct vt8500_port *vt8500_port = vt8500_uart_ports[co->index]; | ||
465 | unsigned long ier; | ||
466 | |||
467 | BUG_ON(co->index < 0 || co->index >= vt8500_uart_driver.nr); | ||
468 | |||
469 | ier = vt8500_read(&vt8500_port->uart, VT8500_URIER); | ||
470 | vt8500_write(&vt8500_port->uart, VT8500_URIER, 0); | ||
471 | |||
472 | uart_console_write(&vt8500_port->uart, s, count, | ||
473 | vt8500_console_putchar); | ||
474 | |||
475 | /* | ||
476 | * Finally, wait for transmitter to become empty | ||
477 | * and switch back to FIFO | ||
478 | */ | ||
479 | wait_for_xmitr(&vt8500_port->uart); | ||
480 | vt8500_write(&vt8500_port->uart, VT8500_URIER, ier); | ||
481 | } | ||
482 | |||
483 | static int __init vt8500_console_setup(struct console *co, char *options) | ||
484 | { | ||
485 | struct vt8500_port *vt8500_port; | ||
486 | int baud = 9600; | ||
487 | int bits = 8; | ||
488 | int parity = 'n'; | ||
489 | int flow = 'n'; | ||
490 | |||
491 | if (unlikely(co->index >= vt8500_uart_driver.nr || co->index < 0)) | ||
492 | return -ENXIO; | ||
493 | |||
494 | vt8500_port = vt8500_uart_ports[co->index]; | ||
495 | |||
496 | if (!vt8500_port) | ||
497 | return -ENODEV; | ||
498 | |||
499 | if (options) | ||
500 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
501 | |||
502 | return uart_set_options(&vt8500_port->uart, | ||
503 | co, baud, parity, bits, flow); | ||
504 | } | ||
505 | |||
506 | static struct console vt8500_console = { | ||
507 | .name = "ttyWMT", | ||
508 | .write = vt8500_console_write, | ||
509 | .device = uart_console_device, | ||
510 | .setup = vt8500_console_setup, | ||
511 | .flags = CON_PRINTBUFFER, | ||
512 | .index = -1, | ||
513 | .data = &vt8500_uart_driver, | ||
514 | }; | ||
515 | |||
516 | #define VT8500_CONSOLE (&vt8500_console) | ||
517 | |||
518 | #else | ||
519 | #define VT8500_CONSOLE NULL | ||
520 | #endif | ||
521 | |||
522 | static struct uart_ops vt8500_uart_pops = { | ||
523 | .tx_empty = vt8500_tx_empty, | ||
524 | .set_mctrl = vt8500_set_mctrl, | ||
525 | .get_mctrl = vt8500_get_mctrl, | ||
526 | .stop_tx = vt8500_stop_tx, | ||
527 | .start_tx = vt8500_start_tx, | ||
528 | .stop_rx = vt8500_stop_rx, | ||
529 | .enable_ms = vt8500_enable_ms, | ||
530 | .break_ctl = vt8500_break_ctl, | ||
531 | .startup = vt8500_startup, | ||
532 | .shutdown = vt8500_shutdown, | ||
533 | .set_termios = vt8500_set_termios, | ||
534 | .type = vt8500_type, | ||
535 | .release_port = vt8500_release_port, | ||
536 | .request_port = vt8500_request_port, | ||
537 | .config_port = vt8500_config_port, | ||
538 | .verify_port = vt8500_verify_port, | ||
539 | }; | ||
540 | |||
541 | static struct uart_driver vt8500_uart_driver = { | ||
542 | .owner = THIS_MODULE, | ||
543 | .driver_name = "vt8500_serial", | ||
544 | .dev_name = "ttyWMT", | ||
545 | .nr = 6, | ||
546 | .cons = VT8500_CONSOLE, | ||
547 | }; | ||
548 | |||
549 | static int __init vt8500_serial_probe(struct platform_device *pdev) | ||
550 | { | ||
551 | struct vt8500_port *vt8500_port; | ||
552 | struct resource *mmres, *irqres; | ||
553 | int ret; | ||
554 | |||
555 | mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
556 | irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
557 | if (!mmres || !irqres) | ||
558 | return -ENODEV; | ||
559 | |||
560 | vt8500_port = kzalloc(sizeof(struct vt8500_port), GFP_KERNEL); | ||
561 | if (!vt8500_port) | ||
562 | return -ENOMEM; | ||
563 | |||
564 | vt8500_port->uart.type = PORT_VT8500; | ||
565 | vt8500_port->uart.iotype = UPIO_MEM; | ||
566 | vt8500_port->uart.mapbase = mmres->start; | ||
567 | vt8500_port->uart.irq = irqres->start; | ||
568 | vt8500_port->uart.fifosize = 16; | ||
569 | vt8500_port->uart.ops = &vt8500_uart_pops; | ||
570 | vt8500_port->uart.line = pdev->id; | ||
571 | vt8500_port->uart.dev = &pdev->dev; | ||
572 | vt8500_port->uart.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; | ||
573 | vt8500_port->uart.uartclk = 24000000; | ||
574 | |||
575 | snprintf(vt8500_port->name, sizeof(vt8500_port->name), | ||
576 | "VT8500 UART%d", pdev->id); | ||
577 | |||
578 | vt8500_port->uart.membase = ioremap(mmres->start, | ||
579 | mmres->end - mmres->start + 1); | ||
580 | if (!vt8500_port->uart.membase) { | ||
581 | ret = -ENOMEM; | ||
582 | goto err; | ||
583 | } | ||
584 | |||
585 | vt8500_uart_ports[pdev->id] = vt8500_port; | ||
586 | |||
587 | uart_add_one_port(&vt8500_uart_driver, &vt8500_port->uart); | ||
588 | |||
589 | platform_set_drvdata(pdev, vt8500_port); | ||
590 | |||
591 | return 0; | ||
592 | |||
593 | err: | ||
594 | kfree(vt8500_port); | ||
595 | return ret; | ||
596 | } | ||
597 | |||
598 | static int __devexit vt8500_serial_remove(struct platform_device *pdev) | ||
599 | { | ||
600 | struct vt8500_port *vt8500_port = platform_get_drvdata(pdev); | ||
601 | |||
602 | platform_set_drvdata(pdev, NULL); | ||
603 | uart_remove_one_port(&vt8500_uart_driver, &vt8500_port->uart); | ||
604 | kfree(vt8500_port); | ||
605 | |||
606 | return 0; | ||
607 | } | ||
608 | |||
609 | static struct platform_driver vt8500_platform_driver = { | ||
610 | .probe = vt8500_serial_probe, | ||
611 | .remove = vt8500_serial_remove, | ||
612 | .driver = { | ||
613 | .name = "vt8500_serial", | ||
614 | .owner = THIS_MODULE, | ||
615 | }, | ||
616 | }; | ||
617 | |||
618 | static int __init vt8500_serial_init(void) | ||
619 | { | ||
620 | int ret; | ||
621 | |||
622 | ret = uart_register_driver(&vt8500_uart_driver); | ||
623 | if (unlikely(ret)) | ||
624 | return ret; | ||
625 | |||
626 | ret = platform_driver_register(&vt8500_platform_driver); | ||
627 | |||
628 | if (unlikely(ret)) | ||
629 | uart_unregister_driver(&vt8500_uart_driver); | ||
630 | |||
631 | return ret; | ||
632 | } | ||
633 | |||
634 | static void __exit vt8500_serial_exit(void) | ||
635 | { | ||
636 | #ifdef CONFIG_SERIAL_VT8500_CONSOLE | ||
637 | unregister_console(&vt8500_console); | ||
638 | #endif | ||
639 | platform_driver_unregister(&vt8500_platform_driver); | ||
640 | uart_unregister_driver(&vt8500_uart_driver); | ||
641 | } | ||
642 | |||
643 | module_init(vt8500_serial_init); | ||
644 | module_exit(vt8500_serial_exit); | ||
645 | |||
646 | MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com>"); | ||
647 | MODULE_DESCRIPTION("Driver for vt8500 serial device"); | ||
648 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/serial/zs.c b/drivers/serial/zs.c index d8c2809b1ab6..1a7fd3e70315 100644 --- a/drivers/serial/zs.c +++ b/drivers/serial/zs.c | |||
@@ -602,12 +602,12 @@ static void zs_receive_chars(struct zs_port *zport) | |||
602 | uart_insert_char(uport, status, Rx_OVR, ch, flag); | 602 | uart_insert_char(uport, status, Rx_OVR, ch, flag); |
603 | } | 603 | } |
604 | 604 | ||
605 | tty_flip_buffer_push(uport->info->port.tty); | 605 | tty_flip_buffer_push(uport->state->port.tty); |
606 | } | 606 | } |
607 | 607 | ||
608 | static void zs_raw_transmit_chars(struct zs_port *zport) | 608 | static void zs_raw_transmit_chars(struct zs_port *zport) |
609 | { | 609 | { |
610 | struct circ_buf *xmit = &zport->port.info->xmit; | 610 | struct circ_buf *xmit = &zport->port.state->xmit; |
611 | 611 | ||
612 | /* XON/XOFF chars. */ | 612 | /* XON/XOFF chars. */ |
613 | if (zport->port.x_char) { | 613 | if (zport->port.x_char) { |
@@ -686,7 +686,7 @@ static void zs_status_handle(struct zs_port *zport, struct zs_port *zport_a) | |||
686 | uport->icount.rng++; | 686 | uport->icount.rng++; |
687 | 687 | ||
688 | if (delta) | 688 | if (delta) |
689 | wake_up_interruptible(&uport->info->delta_msr_wait); | 689 | wake_up_interruptible(&uport->state->port.delta_msr_wait); |
690 | 690 | ||
691 | spin_lock(&scc->zlock); | 691 | spin_lock(&scc->zlock); |
692 | } | 692 | } |