diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-03-08 15:21:04 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-03-08 15:21:04 -0500 |
commit | 988addf82e4c03739375279de73929580a2d4a6a (patch) | |
tree | 989ae1cd4e264bbad80c65f04480486246e7b9f3 /drivers/serial | |
parent | 004c1c7096659d352b83047a7593e91d8a30e3c5 (diff) | |
parent | 25cf84cf377c0aae5dbcf937ea89bc7893db5176 (diff) |
Merge branch 'origin' into devel-stable
Conflicts:
arch/arm/mach-mx2/devices.c
arch/arm/mach-mx2/devices.h
sound/soc/pxa/pxa-ssp.c
Diffstat (limited to 'drivers/serial')
-rw-r--r-- | drivers/serial/68328serial.c | 8 | ||||
-rw-r--r-- | drivers/serial/8250.c | 36 | ||||
-rw-r--r-- | drivers/serial/8250_pci.c | 31 | ||||
-rw-r--r-- | drivers/serial/Kconfig | 69 | ||||
-rw-r--r-- | drivers/serial/amba-pl011.c | 19 | ||||
-rw-r--r-- | drivers/serial/atmel_serial.c | 22 | ||||
-rw-r--r-- | drivers/serial/bcm63xx_uart.c | 7 | ||||
-rw-r--r-- | drivers/serial/bfin_5xx.c | 22 | ||||
-rw-r--r-- | drivers/serial/bfin_sport_uart.c | 701 | ||||
-rw-r--r-- | drivers/serial/bfin_sport_uart.h | 38 | ||||
-rw-r--r-- | drivers/serial/icom.c | 5 | ||||
-rw-r--r-- | drivers/serial/imx.c | 6 | ||||
-rw-r--r-- | drivers/serial/ioc3_serial.c | 3 | ||||
-rw-r--r-- | drivers/serial/jsm/jsm_driver.c | 1 | ||||
-rw-r--r-- | drivers/serial/jsm/jsm_tty.c | 9 | ||||
-rw-r--r-- | drivers/serial/mpc52xx_uart.c | 251 | ||||
-rw-r--r-- | drivers/serial/msm_serial.c | 6 | ||||
-rw-r--r-- | drivers/serial/pmac_zilog.c | 246 | ||||
-rw-r--r-- | drivers/serial/pmac_zilog.h | 34 | ||||
-rw-r--r-- | drivers/serial/serial_cs.c | 7 | ||||
-rw-r--r-- | drivers/serial/sh-sci.c | 616 | ||||
-rw-r--r-- | drivers/serial/timbuart.c | 7 |
22 files changed, 1664 insertions, 480 deletions
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c index d935b2d04f93..ae0251ef6f4e 100644 --- a/drivers/serial/68328serial.c +++ b/drivers/serial/68328serial.c | |||
@@ -153,8 +153,6 @@ static int baud_table[] = { | |||
153 | 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, | 153 | 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, |
154 | 9600, 19200, 38400, 57600, 115200, 0 }; | 154 | 9600, 19200, 38400, 57600, 115200, 0 }; |
155 | 155 | ||
156 | #define BAUD_TABLE_SIZE (sizeof(baud_table)/sizeof(baud_table[0])) | ||
157 | |||
158 | /* Sets or clears DTR/RTS on the requested line */ | 156 | /* Sets or clears DTR/RTS on the requested line */ |
159 | static inline void m68k_rtsdtr(struct m68k_serial *ss, int set) | 157 | static inline void m68k_rtsdtr(struct m68k_serial *ss, int set) |
160 | { | 158 | { |
@@ -1406,10 +1404,10 @@ static void m68328_set_baud(void) | |||
1406 | USTCNT = ustcnt & ~USTCNT_TXEN; | 1404 | USTCNT = ustcnt & ~USTCNT_TXEN; |
1407 | 1405 | ||
1408 | again: | 1406 | again: |
1409 | for (i = 0; i < sizeof(baud_table) / sizeof(baud_table[0]); i++) | 1407 | for (i = 0; i < ARRAY_SIZE(baud_table); i++) |
1410 | if (baud_table[i] == m68328_console_baud) | 1408 | if (baud_table[i] == m68328_console_baud) |
1411 | break; | 1409 | break; |
1412 | if (i >= sizeof(baud_table) / sizeof(baud_table[0])) { | 1410 | if (i >= ARRAY_SIZE(baud_table)) { |
1413 | m68328_console_baud = 9600; | 1411 | m68328_console_baud = 9600; |
1414 | goto again; | 1412 | goto again; |
1415 | } | 1413 | } |
@@ -1435,7 +1433,7 @@ int m68328_console_setup(struct console *cp, char *arg) | |||
1435 | if (arg) | 1433 | if (arg) |
1436 | n = simple_strtoul(arg,NULL,0); | 1434 | n = simple_strtoul(arg,NULL,0); |
1437 | 1435 | ||
1438 | for (i = 0; i < BAUD_TABLE_SIZE; i++) | 1436 | for (i = 0; i < ARRAY_SIZE(baud_table); i++) |
1439 | if (baud_table[i] == n) | 1437 | if (baud_table[i] == n) |
1440 | break; | 1438 | break; |
1441 | if (i < BAUD_TABLE_SIZE) { | 1439 | if (i < BAUD_TABLE_SIZE) { |
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index e9b15c3746fa..7c4ebe6ee18b 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -1217,12 +1217,6 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) | |||
1217 | } | 1217 | } |
1218 | #endif | 1218 | #endif |
1219 | 1219 | ||
1220 | #ifdef CONFIG_SERIAL_8250_AU1X00 | ||
1221 | /* if access method is AU, it is a 16550 with a quirk */ | ||
1222 | if (up->port.type == PORT_16550A && up->port.iotype == UPIO_AU) | ||
1223 | up->bugs |= UART_BUG_NOMSR; | ||
1224 | #endif | ||
1225 | |||
1226 | serial_outp(up, UART_LCR, save_lcr); | 1220 | serial_outp(up, UART_LCR, save_lcr); |
1227 | 1221 | ||
1228 | if (up->capabilities != uart_config[up->port.type].flags) { | 1222 | if (up->capabilities != uart_config[up->port.type].flags) { |
@@ -2428,7 +2422,7 @@ serial8250_pm(struct uart_port *port, unsigned int state, | |||
2428 | static unsigned int serial8250_port_size(struct uart_8250_port *pt) | 2422 | static unsigned int serial8250_port_size(struct uart_8250_port *pt) |
2429 | { | 2423 | { |
2430 | if (pt->port.iotype == UPIO_AU) | 2424 | if (pt->port.iotype == UPIO_AU) |
2431 | return 0x100000; | 2425 | return 0x1000; |
2432 | #ifdef CONFIG_ARCH_OMAP | 2426 | #ifdef CONFIG_ARCH_OMAP |
2433 | if (is_omap_port(pt)) | 2427 | if (is_omap_port(pt)) |
2434 | return 0x16 << pt->port.regshift; | 2428 | return 0x16 << pt->port.regshift; |
@@ -2585,6 +2579,13 @@ static void serial8250_config_port(struct uart_port *port, int flags) | |||
2585 | 2579 | ||
2586 | if (flags & UART_CONFIG_TYPE) | 2580 | if (flags & UART_CONFIG_TYPE) |
2587 | autoconfig(up, probeflags); | 2581 | autoconfig(up, probeflags); |
2582 | |||
2583 | #ifdef CONFIG_SERIAL_8250_AU1X00 | ||
2584 | /* if access method is AU, it is a 16550 with a quirk */ | ||
2585 | if (up->port.type == PORT_16550A && up->port.iotype == UPIO_AU) | ||
2586 | up->bugs |= UART_BUG_NOMSR; | ||
2587 | #endif | ||
2588 | |||
2588 | if (up->port.type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ) | 2589 | if (up->port.type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ) |
2589 | autoconfig_irq(up); | 2590 | autoconfig_irq(up); |
2590 | 2591 | ||
@@ -2689,6 +2690,15 @@ static void __init serial8250_isa_init_ports(void) | |||
2689 | } | 2690 | } |
2690 | } | 2691 | } |
2691 | 2692 | ||
2693 | static void | ||
2694 | serial8250_init_fixed_type_port(struct uart_8250_port *up, unsigned int type) | ||
2695 | { | ||
2696 | up->port.type = type; | ||
2697 | up->port.fifosize = uart_config[type].fifo_size; | ||
2698 | up->capabilities = uart_config[type].flags; | ||
2699 | up->tx_loadsz = uart_config[type].tx_loadsz; | ||
2700 | } | ||
2701 | |||
2692 | static void __init | 2702 | static void __init |
2693 | serial8250_register_ports(struct uart_driver *drv, struct device *dev) | 2703 | serial8250_register_ports(struct uart_driver *drv, struct device *dev) |
2694 | { | 2704 | { |
@@ -2705,6 +2715,10 @@ serial8250_register_ports(struct uart_driver *drv, struct device *dev) | |||
2705 | struct uart_8250_port *up = &serial8250_ports[i]; | 2715 | struct uart_8250_port *up = &serial8250_ports[i]; |
2706 | 2716 | ||
2707 | up->port.dev = dev; | 2717 | up->port.dev = dev; |
2718 | |||
2719 | if (up->port.flags & UPF_FIXED_TYPE) | ||
2720 | serial8250_init_fixed_type_port(up, up->port.type); | ||
2721 | |||
2708 | uart_add_one_port(drv, &up->port); | 2722 | uart_add_one_port(drv, &up->port); |
2709 | } | 2723 | } |
2710 | } | 2724 | } |
@@ -3117,12 +3131,8 @@ int serial8250_register_port(struct uart_port *port) | |||
3117 | if (port->dev) | 3131 | if (port->dev) |
3118 | uart->port.dev = port->dev; | 3132 | uart->port.dev = port->dev; |
3119 | 3133 | ||
3120 | if (port->flags & UPF_FIXED_TYPE) { | 3134 | if (port->flags & UPF_FIXED_TYPE) |
3121 | uart->port.type = port->type; | 3135 | serial8250_init_fixed_type_port(uart, port->type); |
3122 | uart->port.fifosize = uart_config[port->type].fifo_size; | ||
3123 | uart->capabilities = uart_config[port->type].flags; | ||
3124 | uart->tx_loadsz = uart_config[port->type].tx_loadsz; | ||
3125 | } | ||
3126 | 3136 | ||
3127 | set_io_from_upio(&uart->port); | 3137 | set_io_from_upio(&uart->port); |
3128 | /* Possibly override default I/O functions. */ | 3138 | /* Possibly override default I/O functions. */ |
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index b28af13c45a1..01c012da4e26 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c | |||
@@ -760,7 +760,8 @@ static int pci_netmos_init(struct pci_dev *dev) | |||
760 | /* subdevice 0x00PS means <P> parallel, <S> serial */ | 760 | /* subdevice 0x00PS means <P> parallel, <S> serial */ |
761 | unsigned int num_serial = dev->subsystem_device & 0xf; | 761 | unsigned int num_serial = dev->subsystem_device & 0xf; |
762 | 762 | ||
763 | if (dev->device == PCI_DEVICE_ID_NETMOS_9901) | 763 | if ((dev->device == PCI_DEVICE_ID_NETMOS_9901) || |
764 | (dev->device == PCI_DEVICE_ID_NETMOS_9865)) | ||
764 | return 0; | 765 | return 0; |
765 | if (dev->subsystem_vendor == PCI_VENDOR_ID_IBM && | 766 | if (dev->subsystem_vendor == PCI_VENDOR_ID_IBM && |
766 | dev->subsystem_device == 0x0299) | 767 | dev->subsystem_device == 0x0299) |
@@ -1479,6 +1480,7 @@ enum pci_board_num_t { | |||
1479 | 1480 | ||
1480 | pbn_b0_bt_1_115200, | 1481 | pbn_b0_bt_1_115200, |
1481 | pbn_b0_bt_2_115200, | 1482 | pbn_b0_bt_2_115200, |
1483 | pbn_b0_bt_4_115200, | ||
1482 | pbn_b0_bt_8_115200, | 1484 | pbn_b0_bt_8_115200, |
1483 | 1485 | ||
1484 | pbn_b0_bt_1_460800, | 1486 | pbn_b0_bt_1_460800, |
@@ -1703,6 +1705,12 @@ static struct pciserial_board pci_boards[] __devinitdata = { | |||
1703 | .base_baud = 115200, | 1705 | .base_baud = 115200, |
1704 | .uart_offset = 8, | 1706 | .uart_offset = 8, |
1705 | }, | 1707 | }, |
1708 | [pbn_b0_bt_4_115200] = { | ||
1709 | .flags = FL_BASE0|FL_BASE_BARS, | ||
1710 | .num_ports = 4, | ||
1711 | .base_baud = 115200, | ||
1712 | .uart_offset = 8, | ||
1713 | }, | ||
1706 | [pbn_b0_bt_8_115200] = { | 1714 | [pbn_b0_bt_8_115200] = { |
1707 | .flags = FL_BASE0|FL_BASE_BARS, | 1715 | .flags = FL_BASE0|FL_BASE_BARS, |
1708 | .num_ports = 8, | 1716 | .num_ports = 8, |
@@ -3191,6 +3199,15 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
3191 | 0x1208, 0x0004, 0, 0, | 3199 | 0x1208, 0x0004, 0, 0, |
3192 | pbn_b0_4_921600 }, | 3200 | pbn_b0_4_921600 }, |
3193 | 3201 | ||
3202 | { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF2, | ||
3203 | 0x1204, 0x0004, 0, 0, | ||
3204 | pbn_b0_4_921600 }, | ||
3205 | { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF2, | ||
3206 | 0x1208, 0x0004, 0, 0, | ||
3207 | pbn_b0_4_921600 }, | ||
3208 | { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF3, | ||
3209 | 0x1208, 0x0004, 0, 0, | ||
3210 | pbn_b0_4_921600 }, | ||
3194 | /* | 3211 | /* |
3195 | * Dell Remote Access Card 4 - Tim_T_Murphy@Dell.com | 3212 | * Dell Remote Access Card 4 - Tim_T_Murphy@Dell.com |
3196 | */ | 3213 | */ |
@@ -3649,6 +3666,18 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
3649 | 0, 0, pbn_b0_1_115200 }, | 3666 | 0, 0, pbn_b0_1_115200 }, |
3650 | 3667 | ||
3651 | /* | 3668 | /* |
3669 | * Best Connectivity PCI Multi I/O cards | ||
3670 | */ | ||
3671 | |||
3672 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865, | ||
3673 | 0xA000, 0x1000, | ||
3674 | 0, 0, pbn_b0_1_115200 }, | ||
3675 | |||
3676 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865, | ||
3677 | 0xA000, 0x3004, | ||
3678 | 0, 0, pbn_b0_bt_4_115200 }, | ||
3679 | |||
3680 | /* | ||
3652 | * These entries match devices with class COMMUNICATION_SERIAL, | 3681 | * These entries match devices with class COMMUNICATION_SERIAL, |
3653 | * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL | 3682 | * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL |
3654 | */ | 3683 | */ |
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 5351848cfff7..f55c49475a8c 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig | |||
@@ -1026,6 +1026,10 @@ config SERIAL_SH_SCI_CONSOLE | |||
1026 | depends on SERIAL_SH_SCI=y | 1026 | depends on SERIAL_SH_SCI=y |
1027 | select SERIAL_CORE_CONSOLE | 1027 | select SERIAL_CORE_CONSOLE |
1028 | 1028 | ||
1029 | config SERIAL_SH_SCI_DMA | ||
1030 | bool "DMA support" | ||
1031 | depends on SERIAL_SH_SCI && SH_DMAE && EXPERIMENTAL | ||
1032 | |||
1029 | config SERIAL_PNX8XXX | 1033 | config SERIAL_PNX8XXX |
1030 | bool "Enable PNX8XXX SoCs' UART Support" | 1034 | bool "Enable PNX8XXX SoCs' UART Support" |
1031 | depends on MIPS && (SOC_PNX8550 || SOC_PNX833X) | 1035 | depends on MIPS && (SOC_PNX8550 || SOC_PNX833X) |
@@ -1103,12 +1107,12 @@ config SERIAL_68360 | |||
1103 | default y | 1107 | default y |
1104 | 1108 | ||
1105 | config SERIAL_PMACZILOG | 1109 | config SERIAL_PMACZILOG |
1106 | tristate "PowerMac z85c30 ESCC support" | 1110 | tristate "Mac or PowerMac z85c30 ESCC support" |
1107 | depends on PPC_OF && PPC_PMAC | 1111 | depends on (M68K && MAC) || (PPC_OF && PPC_PMAC) |
1108 | select SERIAL_CORE | 1112 | select SERIAL_CORE |
1109 | help | 1113 | help |
1110 | This driver supports the Zilog z85C30 serial ports found on | 1114 | This driver supports the Zilog z85C30 serial ports found on |
1111 | PowerMac machines. | 1115 | (Power)Mac machines. |
1112 | Say Y or M if you want to be able to these serial ports. | 1116 | Say Y or M if you want to be able to these serial ports. |
1113 | 1117 | ||
1114 | config SERIAL_PMACZILOG_TTYS | 1118 | config SERIAL_PMACZILOG_TTYS |
@@ -1133,16 +1137,16 @@ config SERIAL_PMACZILOG_TTYS | |||
1133 | unable to use the 8250 module for PCMCIA or other 16C550-style | 1137 | unable to use the 8250 module for PCMCIA or other 16C550-style |
1134 | UARTs. | 1138 | UARTs. |
1135 | 1139 | ||
1136 | Say N unless you need the z85c30 ports on your powermac | 1140 | Say N unless you need the z85c30 ports on your (Power)Mac |
1137 | to appear as /dev/ttySn. | 1141 | to appear as /dev/ttySn. |
1138 | 1142 | ||
1139 | config SERIAL_PMACZILOG_CONSOLE | 1143 | config SERIAL_PMACZILOG_CONSOLE |
1140 | bool "Console on PowerMac z85c30 serial port" | 1144 | bool "Console on Mac or PowerMac z85c30 serial port" |
1141 | depends on SERIAL_PMACZILOG=y | 1145 | depends on SERIAL_PMACZILOG=y |
1142 | select SERIAL_CORE_CONSOLE | 1146 | select SERIAL_CORE_CONSOLE |
1143 | help | 1147 | help |
1144 | If you would like to be able to use the z85c30 serial port | 1148 | If you would like to be able to use the z85c30 serial port |
1145 | on your PowerMac as the console, you can do so by answering | 1149 | on your (Power)Mac as the console, you can do so by answering |
1146 | Y to this option. | 1150 | Y to this option. |
1147 | 1151 | ||
1148 | config SERIAL_LH7A40X | 1152 | config SERIAL_LH7A40X |
@@ -1435,42 +1439,37 @@ config SERIAL_BFIN_SPORT | |||
1435 | To compile this driver as a module, choose M here: the | 1439 | To compile this driver as a module, choose M here: the |
1436 | module will be called bfin_sport_uart. | 1440 | module will be called bfin_sport_uart. |
1437 | 1441 | ||
1438 | choice | 1442 | config SERIAL_BFIN_SPORT_CONSOLE |
1439 | prompt "Baud rate for Blackfin SPORT UART" | 1443 | bool "Console on Blackfin sport emulated uart" |
1440 | depends on SERIAL_BFIN_SPORT | 1444 | depends on SERIAL_BFIN_SPORT=y |
1441 | default SERIAL_SPORT_BAUD_RATE_57600 | 1445 | select SERIAL_CORE_CONSOLE |
1442 | help | ||
1443 | Choose a baud rate for the SPORT UART, other uart settings are | ||
1444 | 8 bit, 1 stop bit, no parity, no flow control. | ||
1445 | |||
1446 | config SERIAL_SPORT_BAUD_RATE_115200 | ||
1447 | bool "115200" | ||
1448 | |||
1449 | config SERIAL_SPORT_BAUD_RATE_57600 | ||
1450 | bool "57600" | ||
1451 | 1446 | ||
1452 | config SERIAL_SPORT_BAUD_RATE_38400 | 1447 | config SERIAL_BFIN_SPORT0_UART |
1453 | bool "38400" | 1448 | bool "Enable UART over SPORT0" |
1449 | depends on SERIAL_BFIN_SPORT && !(BF542 || BF542M || BF544 || BF544M) | ||
1450 | help | ||
1451 | Enable UART over SPORT0 | ||
1454 | 1452 | ||
1455 | config SERIAL_SPORT_BAUD_RATE_19200 | 1453 | config SERIAL_BFIN_SPORT1_UART |
1456 | bool "19200" | 1454 | bool "Enable UART over SPORT1" |
1455 | depends on SERIAL_BFIN_SPORT | ||
1456 | help | ||
1457 | Enable UART over SPORT1 | ||
1457 | 1458 | ||
1458 | config SERIAL_SPORT_BAUD_RATE_9600 | 1459 | config SERIAL_BFIN_SPORT2_UART |
1459 | bool "9600" | 1460 | bool "Enable UART over SPORT2" |
1460 | endchoice | 1461 | depends on SERIAL_BFIN_SPORT && (BF54x || BF538 || BF539) |
1462 | help | ||
1463 | Enable UART over SPORT2 | ||
1461 | 1464 | ||
1462 | config SPORT_BAUD_RATE | 1465 | config SERIAL_BFIN_SPORT3_UART |
1463 | int | 1466 | bool "Enable UART over SPORT3" |
1464 | depends on SERIAL_BFIN_SPORT | 1467 | depends on SERIAL_BFIN_SPORT && (BF54x || BF538 || BF539) |
1465 | default 115200 if (SERIAL_SPORT_BAUD_RATE_115200) | 1468 | help |
1466 | default 57600 if (SERIAL_SPORT_BAUD_RATE_57600) | 1469 | Enable UART over SPORT3 |
1467 | default 38400 if (SERIAL_SPORT_BAUD_RATE_38400) | ||
1468 | default 19200 if (SERIAL_SPORT_BAUD_RATE_19200) | ||
1469 | default 9600 if (SERIAL_SPORT_BAUD_RATE_9600) | ||
1470 | 1470 | ||
1471 | config SERIAL_TIMBERDALE | 1471 | config SERIAL_TIMBERDALE |
1472 | tristate "Support for timberdale UART" | 1472 | tristate "Support for timberdale UART" |
1473 | depends on MFD_TIMBERDALE | ||
1474 | select SERIAL_CORE | 1473 | select SERIAL_CORE |
1475 | ---help--- | 1474 | ---help--- |
1476 | Add support for UART controller on timberdale. | 1475 | Add support for UART controller on timberdale. |
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c index ef7adc8135dd..ce6c35333ff7 100644 --- a/drivers/serial/amba-pl011.c +++ b/drivers/serial/amba-pl011.c | |||
@@ -71,6 +71,7 @@ struct uart_amba_port { | |||
71 | unsigned int im; /* interrupt mask */ | 71 | unsigned int im; /* interrupt mask */ |
72 | unsigned int old_status; | 72 | unsigned int old_status; |
73 | unsigned int ifls; /* vendor-specific */ | 73 | unsigned int ifls; /* vendor-specific */ |
74 | bool autorts; | ||
74 | }; | 75 | }; |
75 | 76 | ||
76 | /* There is by now at least one vendor with differing details, so handle it */ | 77 | /* There is by now at least one vendor with differing details, so handle it */ |
@@ -308,6 +309,11 @@ static void pl011_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
308 | TIOCMBIT(TIOCM_OUT1, UART011_CR_OUT1); | 309 | TIOCMBIT(TIOCM_OUT1, UART011_CR_OUT1); |
309 | TIOCMBIT(TIOCM_OUT2, UART011_CR_OUT2); | 310 | TIOCMBIT(TIOCM_OUT2, UART011_CR_OUT2); |
310 | TIOCMBIT(TIOCM_LOOP, UART011_CR_LBE); | 311 | TIOCMBIT(TIOCM_LOOP, UART011_CR_LBE); |
312 | |||
313 | if (uap->autorts) { | ||
314 | /* We need to disable auto-RTS if we want to turn RTS off */ | ||
315 | TIOCMBIT(TIOCM_RTS, UART011_CR_RTSEN); | ||
316 | } | ||
311 | #undef TIOCMBIT | 317 | #undef TIOCMBIT |
312 | 318 | ||
313 | writew(cr, uap->port.membase + UART011_CR); | 319 | writew(cr, uap->port.membase + UART011_CR); |
@@ -437,6 +443,7 @@ static void pl011_shutdown(struct uart_port *port) | |||
437 | /* | 443 | /* |
438 | * disable the port | 444 | * disable the port |
439 | */ | 445 | */ |
446 | uap->autorts = false; | ||
440 | writew(UART01x_CR_UARTEN | UART011_CR_TXE, uap->port.membase + UART011_CR); | 447 | writew(UART01x_CR_UARTEN | UART011_CR_TXE, uap->port.membase + UART011_CR); |
441 | 448 | ||
442 | /* | 449 | /* |
@@ -456,6 +463,7 @@ static void | |||
456 | pl011_set_termios(struct uart_port *port, struct ktermios *termios, | 463 | pl011_set_termios(struct uart_port *port, struct ktermios *termios, |
457 | struct ktermios *old) | 464 | struct ktermios *old) |
458 | { | 465 | { |
466 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | ||
459 | unsigned int lcr_h, old_cr; | 467 | unsigned int lcr_h, old_cr; |
460 | unsigned long flags; | 468 | unsigned long flags; |
461 | unsigned int baud, quot; | 469 | unsigned int baud, quot; |
@@ -532,6 +540,17 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, | |||
532 | old_cr = readw(port->membase + UART011_CR); | 540 | old_cr = readw(port->membase + UART011_CR); |
533 | writew(0, port->membase + UART011_CR); | 541 | writew(0, port->membase + UART011_CR); |
534 | 542 | ||
543 | if (termios->c_cflag & CRTSCTS) { | ||
544 | if (old_cr & UART011_CR_RTS) | ||
545 | old_cr |= UART011_CR_RTSEN; | ||
546 | |||
547 | old_cr |= UART011_CR_CTSEN; | ||
548 | uap->autorts = true; | ||
549 | } else { | ||
550 | old_cr &= ~(UART011_CR_CTSEN | UART011_CR_RTSEN); | ||
551 | uap->autorts = false; | ||
552 | } | ||
553 | |||
535 | /* Set baud rate */ | 554 | /* Set baud rate */ |
536 | writew(quot & 0x3f, port->membase + UART011_FBRD); | 555 | writew(quot & 0x3f, port->membase + UART011_FBRD); |
537 | writew(quot >> 6, port->membase + UART011_IBRD); | 556 | writew(quot >> 6, port->membase + UART011_IBRD); |
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c index 9d948bccafaf..2c9bf9b68327 100644 --- a/drivers/serial/atmel_serial.c +++ b/drivers/serial/atmel_serial.c | |||
@@ -1213,6 +1213,24 @@ static int atmel_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
1213 | return ret; | 1213 | return ret; |
1214 | } | 1214 | } |
1215 | 1215 | ||
1216 | #ifdef CONFIG_CONSOLE_POLL | ||
1217 | static int atmel_poll_get_char(struct uart_port *port) | ||
1218 | { | ||
1219 | while (!(UART_GET_CSR(port) & ATMEL_US_RXRDY)) | ||
1220 | cpu_relax(); | ||
1221 | |||
1222 | return UART_GET_CHAR(port); | ||
1223 | } | ||
1224 | |||
1225 | static void atmel_poll_put_char(struct uart_port *port, unsigned char ch) | ||
1226 | { | ||
1227 | while (!(UART_GET_CSR(port) & ATMEL_US_TXRDY)) | ||
1228 | cpu_relax(); | ||
1229 | |||
1230 | UART_PUT_CHAR(port, ch); | ||
1231 | } | ||
1232 | #endif | ||
1233 | |||
1216 | static struct uart_ops atmel_pops = { | 1234 | static struct uart_ops atmel_pops = { |
1217 | .tx_empty = atmel_tx_empty, | 1235 | .tx_empty = atmel_tx_empty, |
1218 | .set_mctrl = atmel_set_mctrl, | 1236 | .set_mctrl = atmel_set_mctrl, |
@@ -1232,6 +1250,10 @@ static struct uart_ops atmel_pops = { | |||
1232 | .config_port = atmel_config_port, | 1250 | .config_port = atmel_config_port, |
1233 | .verify_port = atmel_verify_port, | 1251 | .verify_port = atmel_verify_port, |
1234 | .pm = atmel_serial_pm, | 1252 | .pm = atmel_serial_pm, |
1253 | #ifdef CONFIG_CONSOLE_POLL | ||
1254 | .poll_get_char = atmel_poll_get_char, | ||
1255 | .poll_put_char = atmel_poll_put_char, | ||
1256 | #endif | ||
1235 | }; | 1257 | }; |
1236 | 1258 | ||
1237 | /* | 1259 | /* |
diff --git a/drivers/serial/bcm63xx_uart.c b/drivers/serial/bcm63xx_uart.c index 37ad0c449937..a1a0e55d0807 100644 --- a/drivers/serial/bcm63xx_uart.c +++ b/drivers/serial/bcm63xx_uart.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include <bcm63xx_regs.h> | 35 | #include <bcm63xx_regs.h> |
36 | #include <bcm63xx_io.h> | 36 | #include <bcm63xx_io.h> |
37 | 37 | ||
38 | #define BCM63XX_NR_UARTS 1 | 38 | #define BCM63XX_NR_UARTS 2 |
39 | 39 | ||
40 | static struct uart_port ports[BCM63XX_NR_UARTS]; | 40 | static struct uart_port ports[BCM63XX_NR_UARTS]; |
41 | 41 | ||
@@ -784,7 +784,7 @@ static struct uart_driver bcm_uart_driver = { | |||
784 | .dev_name = "ttyS", | 784 | .dev_name = "ttyS", |
785 | .major = TTY_MAJOR, | 785 | .major = TTY_MAJOR, |
786 | .minor = 64, | 786 | .minor = 64, |
787 | .nr = 1, | 787 | .nr = BCM63XX_NR_UARTS, |
788 | .cons = BCM63XX_CONSOLE, | 788 | .cons = BCM63XX_CONSOLE, |
789 | }; | 789 | }; |
790 | 790 | ||
@@ -826,11 +826,12 @@ static int __devinit bcm_uart_probe(struct platform_device *pdev) | |||
826 | port->dev = &pdev->dev; | 826 | port->dev = &pdev->dev; |
827 | port->fifosize = 16; | 827 | port->fifosize = 16; |
828 | port->uartclk = clk_get_rate(clk) / 2; | 828 | port->uartclk = clk_get_rate(clk) / 2; |
829 | port->line = pdev->id; | ||
829 | clk_put(clk); | 830 | clk_put(clk); |
830 | 831 | ||
831 | ret = uart_add_one_port(&bcm_uart_driver, port); | 832 | ret = uart_add_one_port(&bcm_uart_driver, port); |
832 | if (ret) { | 833 | if (ret) { |
833 | kfree(port); | 834 | ports[pdev->id].membase = 0; |
834 | return ret; | 835 | return ret; |
835 | } | 836 | } |
836 | platform_set_drvdata(pdev, port); | 837 | platform_set_drvdata(pdev, port); |
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index 50abb7e557f4..fcf273e3f48c 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c | |||
@@ -14,6 +14,7 @@ | |||
14 | 14 | ||
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/ioport.h> | 16 | #include <linux/ioport.h> |
17 | #include <linux/io.h> | ||
17 | #include <linux/init.h> | 18 | #include <linux/init.h> |
18 | #include <linux/console.h> | 19 | #include <linux/console.h> |
19 | #include <linux/sysrq.h> | 20 | #include <linux/sysrq.h> |
@@ -237,7 +238,8 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart) | |||
237 | 238 | ||
238 | #if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \ | 239 | #if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \ |
239 | defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE) | 240 | defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE) |
240 | if (kgdb_connected && kgdboc_port_line == uart->port.line) | 241 | if (kgdb_connected && kgdboc_port_line == uart->port.line |
242 | && kgdboc_break_enabled) | ||
241 | if (ch == 0x3) {/* Ctrl + C */ | 243 | if (ch == 0x3) {/* Ctrl + C */ |
242 | kgdb_breakpoint(); | 244 | kgdb_breakpoint(); |
243 | return; | 245 | return; |
@@ -488,6 +490,7 @@ void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) | |||
488 | { | 490 | { |
489 | int x_pos, pos; | 491 | int x_pos, pos; |
490 | 492 | ||
493 | dma_disable_irq(uart->tx_dma_channel); | ||
491 | dma_disable_irq(uart->rx_dma_channel); | 494 | dma_disable_irq(uart->rx_dma_channel); |
492 | spin_lock_bh(&uart->port.lock); | 495 | spin_lock_bh(&uart->port.lock); |
493 | 496 | ||
@@ -521,6 +524,7 @@ void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) | |||
521 | } | 524 | } |
522 | 525 | ||
523 | spin_unlock_bh(&uart->port.lock); | 526 | spin_unlock_bh(&uart->port.lock); |
527 | dma_enable_irq(uart->tx_dma_channel); | ||
524 | dma_enable_irq(uart->rx_dma_channel); | 528 | dma_enable_irq(uart->rx_dma_channel); |
525 | 529 | ||
526 | mod_timer(&(uart->rx_dma_timer), jiffies + DMA_RX_FLUSH_JIFFIES); | 530 | mod_timer(&(uart->rx_dma_timer), jiffies + DMA_RX_FLUSH_JIFFIES); |
@@ -746,15 +750,6 @@ static int bfin_serial_startup(struct uart_port *port) | |||
746 | Status interrupt.\n"); | 750 | Status interrupt.\n"); |
747 | } | 751 | } |
748 | 752 | ||
749 | if (uart->cts_pin >= 0) { | ||
750 | gpio_request(uart->cts_pin, DRIVER_NAME); | ||
751 | gpio_direction_output(uart->cts_pin, 1); | ||
752 | } | ||
753 | if (uart->rts_pin >= 0) { | ||
754 | gpio_request(uart->rts_pin, DRIVER_NAME); | ||
755 | gpio_direction_output(uart->rts_pin, 0); | ||
756 | } | ||
757 | |||
758 | /* CTS RTS PINs are negative assertive. */ | 753 | /* CTS RTS PINs are negative assertive. */ |
759 | UART_PUT_MCR(uart, ACTS); | 754 | UART_PUT_MCR(uart, ACTS); |
760 | UART_SET_IER(uart, EDSSI); | 755 | UART_SET_IER(uart, EDSSI); |
@@ -801,10 +796,6 @@ static void bfin_serial_shutdown(struct uart_port *port) | |||
801 | gpio_free(uart->rts_pin); | 796 | gpio_free(uart->rts_pin); |
802 | #endif | 797 | #endif |
803 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS | 798 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS |
804 | if (uart->cts_pin >= 0) | ||
805 | gpio_free(uart->cts_pin); | ||
806 | if (uart->rts_pin >= 0) | ||
807 | gpio_free(uart->rts_pin); | ||
808 | if (UART_GET_IER(uart) && EDSSI) | 799 | if (UART_GET_IER(uart) && EDSSI) |
809 | free_irq(uart->status_irq, uart); | 800 | free_irq(uart->status_irq, uart); |
810 | #endif | 801 | #endif |
@@ -1409,8 +1400,7 @@ static int bfin_serial_remove(struct platform_device *dev) | |||
1409 | continue; | 1400 | continue; |
1410 | uart_remove_one_port(&bfin_serial_reg, &bfin_serial_ports[i].port); | 1401 | uart_remove_one_port(&bfin_serial_reg, &bfin_serial_ports[i].port); |
1411 | bfin_serial_ports[i].port.dev = NULL; | 1402 | bfin_serial_ports[i].port.dev = NULL; |
1412 | #if defined(CONFIG_SERIAL_BFIN_CTSRTS) || \ | 1403 | #if defined(CONFIG_SERIAL_BFIN_CTSRTS) |
1413 | defined(CONFIG_SERIAL_BFIN_HARD_CTSRTS) | ||
1414 | gpio_free(bfin_serial_ports[i].cts_pin); | 1404 | gpio_free(bfin_serial_ports[i].cts_pin); |
1415 | gpio_free(bfin_serial_ports[i].rts_pin); | 1405 | gpio_free(bfin_serial_ports[i].rts_pin); |
1416 | #endif | 1406 | #endif |
diff --git a/drivers/serial/bfin_sport_uart.c b/drivers/serial/bfin_sport_uart.c index 088bb35475f1..7c72888fbf94 100644 --- a/drivers/serial/bfin_sport_uart.c +++ b/drivers/serial/bfin_sport_uart.c | |||
@@ -1,27 +1,11 @@ | |||
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 | /* |
@@ -29,39 +13,18 @@ | |||
29 | * http://www.analog.com/UploadedFiles/Application_Notes/399447663EE191.pdf | 13 | * http://www.analog.com/UploadedFiles/Application_Notes/399447663EE191.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> |
@@ -75,23 +38,36 @@ | |||
75 | 38 | ||
76 | #include "bfin_sport_uart.h" | 39 | #include "bfin_sport_uart.h" |
77 | 40 | ||
41 | #ifdef CONFIG_SERIAL_BFIN_SPORT0_UART | ||
78 | unsigned short bfin_uart_pin_req_sport0[] = | 42 | unsigned short bfin_uart_pin_req_sport0[] = |
79 | {P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, \ | 43 | {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}; | 44 | P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0}; |
81 | 45 | #endif | |
46 | #ifdef CONFIG_SERIAL_BFIN_SPORT1_UART | ||
82 | unsigned short bfin_uart_pin_req_sport1[] = | 47 | unsigned short bfin_uart_pin_req_sport1[] = |
83 | {P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, \ | 48 | {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}; | 49 | P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0}; |
85 | 50 | #endif | |
86 | #define DRV_NAME "bfin-sport-uart" | 51 | #ifdef CONFIG_SERIAL_BFIN_SPORT2_UART |
52 | unsigned short bfin_uart_pin_req_sport2[] = | ||
53 | {P_SPORT2_TFS, P_SPORT2_DTPRI, P_SPORT2_TSCLK, P_SPORT2_RFS, \ | ||
54 | P_SPORT2_DRPRI, P_SPORT2_RSCLK, P_SPORT2_DRSEC, P_SPORT2_DTSEC, 0}; | ||
55 | #endif | ||
56 | #ifdef CONFIG_SERIAL_BFIN_SPORT3_UART | ||
57 | unsigned short bfin_uart_pin_req_sport3[] = | ||
58 | {P_SPORT3_TFS, P_SPORT3_DTPRI, P_SPORT3_TSCLK, P_SPORT3_RFS, \ | ||
59 | P_SPORT3_DRPRI, P_SPORT3_RSCLK, P_SPORT3_DRSEC, P_SPORT3_DTSEC, 0}; | ||
60 | #endif | ||
87 | 61 | ||
88 | struct sport_uart_port { | 62 | struct sport_uart_port { |
89 | struct uart_port port; | 63 | struct uart_port port; |
90 | char *name; | ||
91 | |||
92 | int tx_irq; | ||
93 | int rx_irq; | ||
94 | int err_irq; | 64 | int err_irq; |
65 | unsigned short csize; | ||
66 | unsigned short rxmask; | ||
67 | unsigned short txmask1; | ||
68 | unsigned short txmask2; | ||
69 | unsigned char stopb; | ||
70 | /* unsigned char parib; */ | ||
95 | }; | 71 | }; |
96 | 72 | ||
97 | static void sport_uart_tx_chars(struct sport_uart_port *up); | 73 | static void sport_uart_tx_chars(struct sport_uart_port *up); |
@@ -99,36 +75,42 @@ static void sport_stop_tx(struct uart_port *port); | |||
99 | 75 | ||
100 | static inline void tx_one_byte(struct sport_uart_port *up, unsigned int value) | 76 | static inline void tx_one_byte(struct sport_uart_port *up, unsigned int value) |
101 | { | 77 | { |
102 | pr_debug("%s value:%x\n", __func__, value); | 78 | pr_debug("%s value:%x, mask1=0x%x, mask2=0x%x\n", __func__, value, |
103 | /* Place a Start and Stop bit */ | 79 | up->txmask1, up->txmask2); |
80 | |||
81 | /* Place Start and Stop bits */ | ||
104 | __asm__ __volatile__ ( | 82 | __asm__ __volatile__ ( |
105 | "R2 = b#01111111100;" | 83 | "%[val] <<= 1;" |
106 | "R3 = b#10000000001;" | 84 | "%[val] = %[val] & %[mask1];" |
107 | "%0 <<= 2;" | 85 | "%[val] = %[val] | %[mask2];" |
108 | "%0 = %0 & R2;" | 86 | : [val]"+d"(value) |
109 | "%0 = %0 | R3;" | 87 | : [mask1]"d"(up->txmask1), [mask2]"d"(up->txmask2) |
110 | : "=d"(value) | 88 | : "ASTAT" |
111 | : "d"(value) | ||
112 | : "ASTAT", "R2", "R3" | ||
113 | ); | 89 | ); |
114 | pr_debug("%s value:%x\n", __func__, value); | 90 | pr_debug("%s value:%x\n", __func__, value); |
115 | 91 | ||
116 | SPORT_PUT_TX(up, value); | 92 | SPORT_PUT_TX(up, value); |
117 | } | 93 | } |
118 | 94 | ||
119 | static inline unsigned int rx_one_byte(struct sport_uart_port *up) | 95 | static inline unsigned char rx_one_byte(struct sport_uart_port *up) |
120 | { | 96 | { |
121 | unsigned int value, extract; | 97 | unsigned int value; |
98 | unsigned char extract; | ||
122 | u32 tmp_mask1, tmp_mask2, tmp_shift, tmp; | 99 | u32 tmp_mask1, tmp_mask2, tmp_shift, tmp; |
123 | 100 | ||
124 | value = SPORT_GET_RX32(up); | 101 | if ((up->csize + up->stopb) > 7) |
125 | pr_debug("%s value:%x\n", __func__, value); | 102 | value = SPORT_GET_RX32(up); |
103 | else | ||
104 | value = SPORT_GET_RX(up); | ||
105 | |||
106 | pr_debug("%s value:%x, cs=%d, mask=0x%x\n", __func__, value, | ||
107 | up->csize, up->rxmask); | ||
126 | 108 | ||
127 | /* Extract 8 bits data */ | 109 | /* Extract data */ |
128 | __asm__ __volatile__ ( | 110 | __asm__ __volatile__ ( |
129 | "%[extr] = 0;" | 111 | "%[extr] = 0;" |
130 | "%[mask1] = 0x1801(Z);" | 112 | "%[mask1] = %[rxmask];" |
131 | "%[mask2] = 0x0300(Z);" | 113 | "%[mask2] = 0x0200(Z);" |
132 | "%[shift] = 0;" | 114 | "%[shift] = 0;" |
133 | "LSETUP(.Lloop_s, .Lloop_e) LC0 = %[lc];" | 115 | "LSETUP(.Lloop_s, .Lloop_e) LC0 = %[lc];" |
134 | ".Lloop_s:" | 116 | ".Lloop_s:" |
@@ -138,9 +120,9 @@ static inline unsigned int rx_one_byte(struct sport_uart_port *up) | |||
138 | "%[mask1] = %[mask1] - %[mask2];" | 120 | "%[mask1] = %[mask1] - %[mask2];" |
139 | ".Lloop_e:" | 121 | ".Lloop_e:" |
140 | "%[shift] += 1;" | 122 | "%[shift] += 1;" |
141 | : [val]"=d"(value), [extr]"=d"(extract), [shift]"=d"(tmp_shift), [tmp]"=d"(tmp), | 123 | : [extr]"=&d"(extract), [shift]"=&d"(tmp_shift), [tmp]"=&d"(tmp), |
142 | [mask1]"=d"(tmp_mask1), [mask2]"=d"(tmp_mask2) | 124 | [mask1]"=&d"(tmp_mask1), [mask2]"=&d"(tmp_mask2) |
143 | : "d"(value), [lc]"a"(8) | 125 | : [val]"d"(value), [rxmask]"d"(up->rxmask), [lc]"a"(up->csize) |
144 | : "ASTAT", "LB0", "LC0", "LT0" | 126 | : "ASTAT", "LB0", "LC0", "LT0" |
145 | ); | 127 | ); |
146 | 128 | ||
@@ -148,29 +130,28 @@ static inline unsigned int rx_one_byte(struct sport_uart_port *up) | |||
148 | return extract; | 130 | return extract; |
149 | } | 131 | } |
150 | 132 | ||
151 | static int sport_uart_setup(struct sport_uart_port *up, int sclk, int baud_rate) | 133 | static int sport_uart_setup(struct sport_uart_port *up, int size, int baud_rate) |
152 | { | 134 | { |
153 | int tclkdiv, tfsdiv, rclkdiv; | 135 | int tclkdiv, rclkdiv; |
136 | unsigned int sclk = get_sclk(); | ||
154 | 137 | ||
155 | /* Set TCR1 and TCR2 */ | 138 | /* Set TCR1 and TCR2, TFSR is not enabled for uart */ |
156 | SPORT_PUT_TCR1(up, (LATFS | ITFS | TFSR | TLSBIT | ITCLK)); | 139 | SPORT_PUT_TCR1(up, (ITFS | TLSBIT | ITCLK)); |
157 | SPORT_PUT_TCR2(up, 10); | 140 | SPORT_PUT_TCR2(up, size + 1); |
158 | pr_debug("%s TCR1:%x, TCR2:%x\n", __func__, SPORT_GET_TCR1(up), SPORT_GET_TCR2(up)); | 141 | pr_debug("%s TCR1:%x, TCR2:%x\n", __func__, SPORT_GET_TCR1(up), SPORT_GET_TCR2(up)); |
159 | 142 | ||
160 | /* Set RCR1 and RCR2 */ | 143 | /* Set RCR1 and RCR2 */ |
161 | SPORT_PUT_RCR1(up, (RCKFE | LARFS | LRFS | RFSR | IRCLK)); | 144 | SPORT_PUT_RCR1(up, (RCKFE | LARFS | LRFS | RFSR | IRCLK)); |
162 | SPORT_PUT_RCR2(up, 28); | 145 | 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)); | 146 | pr_debug("%s RCR1:%x, RCR2:%x\n", __func__, SPORT_GET_RCR1(up), SPORT_GET_RCR2(up)); |
164 | 147 | ||
165 | tclkdiv = sclk/(2 * baud_rate) - 1; | 148 | tclkdiv = sclk / (2 * baud_rate) - 1; |
166 | tfsdiv = 12; | 149 | rclkdiv = sclk / (2 * baud_rate * 2) - 1; |
167 | rclkdiv = sclk/(2 * baud_rate * 3) - 1; | ||
168 | SPORT_PUT_TCLKDIV(up, tclkdiv); | 150 | SPORT_PUT_TCLKDIV(up, tclkdiv); |
169 | SPORT_PUT_TFSDIV(up, tfsdiv); | ||
170 | SPORT_PUT_RCLKDIV(up, rclkdiv); | 151 | SPORT_PUT_RCLKDIV(up, rclkdiv); |
171 | SSYNC(); | 152 | SSYNC(); |
172 | pr_debug("%s sclk:%d, baud_rate:%d, tclkdiv:%d, tfsdiv:%d, rclkdiv:%d\n", | 153 | pr_debug("%s sclk:%d, baud_rate:%d, tclkdiv:%d, rclkdiv:%d\n", |
173 | __func__, sclk, baud_rate, tclkdiv, tfsdiv, rclkdiv); | 154 | __func__, sclk, baud_rate, tclkdiv, rclkdiv); |
174 | 155 | ||
175 | return 0; | 156 | return 0; |
176 | } | 157 | } |
@@ -181,23 +162,29 @@ static irqreturn_t sport_uart_rx_irq(int irq, void *dev_id) | |||
181 | struct tty_struct *tty = up->port.state->port.tty; | 162 | struct tty_struct *tty = up->port.state->port.tty; |
182 | unsigned int ch; | 163 | unsigned int ch; |
183 | 164 | ||
184 | do { | 165 | spin_lock(&up->port.lock); |
166 | |||
167 | while (SPORT_GET_STAT(up) & RXNE) { | ||
185 | ch = rx_one_byte(up); | 168 | ch = rx_one_byte(up); |
186 | up->port.icount.rx++; | 169 | up->port.icount.rx++; |
187 | 170 | ||
188 | if (uart_handle_sysrq_char(&up->port, ch)) | 171 | if (!uart_handle_sysrq_char(&up->port, ch)) |
189 | ; | ||
190 | else | ||
191 | tty_insert_flip_char(tty, ch, TTY_NORMAL); | 172 | tty_insert_flip_char(tty, ch, TTY_NORMAL); |
192 | } while (SPORT_GET_STAT(up) & RXNE); | 173 | } |
193 | tty_flip_buffer_push(tty); | 174 | tty_flip_buffer_push(tty); |
194 | 175 | ||
176 | spin_unlock(&up->port.lock); | ||
177 | |||
195 | return IRQ_HANDLED; | 178 | return IRQ_HANDLED; |
196 | } | 179 | } |
197 | 180 | ||
198 | static irqreturn_t sport_uart_tx_irq(int irq, void *dev_id) | 181 | static irqreturn_t sport_uart_tx_irq(int irq, void *dev_id) |
199 | { | 182 | { |
200 | sport_uart_tx_chars(dev_id); | 183 | struct sport_uart_port *up = dev_id; |
184 | |||
185 | spin_lock(&up->port.lock); | ||
186 | sport_uart_tx_chars(up); | ||
187 | spin_unlock(&up->port.lock); | ||
201 | 188 | ||
202 | return IRQ_HANDLED; | 189 | return IRQ_HANDLED; |
203 | } | 190 | } |
@@ -208,6 +195,8 @@ static irqreturn_t sport_uart_err_irq(int irq, void *dev_id) | |||
208 | struct tty_struct *tty = up->port.state->port.tty; | 195 | struct tty_struct *tty = up->port.state->port.tty; |
209 | unsigned int stat = SPORT_GET_STAT(up); | 196 | unsigned int stat = SPORT_GET_STAT(up); |
210 | 197 | ||
198 | spin_lock(&up->port.lock); | ||
199 | |||
211 | /* Overflow in RX FIFO */ | 200 | /* Overflow in RX FIFO */ |
212 | if (stat & ROVF) { | 201 | if (stat & ROVF) { |
213 | up->port.icount.overrun++; | 202 | up->port.icount.overrun++; |
@@ -216,15 +205,16 @@ static irqreturn_t sport_uart_err_irq(int irq, void *dev_id) | |||
216 | } | 205 | } |
217 | /* These should not happen */ | 206 | /* These should not happen */ |
218 | if (stat & (TOVF | TUVF | RUVF)) { | 207 | if (stat & (TOVF | TUVF | RUVF)) { |
219 | printk(KERN_ERR "SPORT Error:%s %s %s\n", | 208 | pr_err("SPORT Error:%s %s %s\n", |
220 | (stat & TOVF)?"TX overflow":"", | 209 | (stat & TOVF) ? "TX overflow" : "", |
221 | (stat & TUVF)?"TX underflow":"", | 210 | (stat & TUVF) ? "TX underflow" : "", |
222 | (stat & RUVF)?"RX underflow":""); | 211 | (stat & RUVF) ? "RX underflow" : ""); |
223 | SPORT_PUT_TCR1(up, SPORT_GET_TCR1(up) & ~TSPEN); | 212 | SPORT_PUT_TCR1(up, SPORT_GET_TCR1(up) & ~TSPEN); |
224 | SPORT_PUT_RCR1(up, SPORT_GET_RCR1(up) & ~RSPEN); | 213 | SPORT_PUT_RCR1(up, SPORT_GET_RCR1(up) & ~RSPEN); |
225 | } | 214 | } |
226 | SSYNC(); | 215 | SSYNC(); |
227 | 216 | ||
217 | spin_unlock(&up->port.lock); | ||
228 | return IRQ_HANDLED; | 218 | return IRQ_HANDLED; |
229 | } | 219 | } |
230 | 220 | ||
@@ -232,60 +222,37 @@ static irqreturn_t sport_uart_err_irq(int irq, void *dev_id) | |||
232 | static int sport_startup(struct uart_port *port) | 222 | static int sport_startup(struct uart_port *port) |
233 | { | 223 | { |
234 | struct sport_uart_port *up = (struct sport_uart_port *)port; | 224 | struct sport_uart_port *up = (struct sport_uart_port *)port; |
235 | char buffer[20]; | 225 | int ret; |
236 | int retval; | ||
237 | 226 | ||
238 | pr_debug("%s enter\n", __func__); | 227 | pr_debug("%s enter\n", __func__); |
239 | snprintf(buffer, 20, "%s rx", up->name); | 228 | ret = request_irq(up->port.irq, sport_uart_rx_irq, 0, |
240 | retval = request_irq(up->rx_irq, sport_uart_rx_irq, IRQF_SAMPLE_RANDOM, buffer, up); | 229 | "SPORT_UART_RX", up); |
241 | if (retval) { | 230 | if (ret) { |
242 | printk(KERN_ERR "Unable to request interrupt %s\n", buffer); | 231 | dev_err(port->dev, "unable to request SPORT RX interrupt\n"); |
243 | return retval; | 232 | return ret; |
244 | } | 233 | } |
245 | 234 | ||
246 | snprintf(buffer, 20, "%s tx", up->name); | 235 | ret = request_irq(up->port.irq+1, sport_uart_tx_irq, 0, |
247 | retval = request_irq(up->tx_irq, sport_uart_tx_irq, IRQF_SAMPLE_RANDOM, buffer, up); | 236 | "SPORT_UART_TX", up); |
248 | if (retval) { | 237 | if (ret) { |
249 | printk(KERN_ERR "Unable to request interrupt %s\n", buffer); | 238 | dev_err(port->dev, "unable to request SPORT TX interrupt\n"); |
250 | goto fail1; | 239 | goto fail1; |
251 | } | 240 | } |
252 | 241 | ||
253 | snprintf(buffer, 20, "%s err", up->name); | 242 | ret = request_irq(up->err_irq, sport_uart_err_irq, 0, |
254 | retval = request_irq(up->err_irq, sport_uart_err_irq, IRQF_SAMPLE_RANDOM, buffer, up); | 243 | "SPORT_UART_STATUS", up); |
255 | if (retval) { | 244 | if (ret) { |
256 | printk(KERN_ERR "Unable to request interrupt %s\n", buffer); | 245 | dev_err(port->dev, "unable to request SPORT status interrupt\n"); |
257 | goto fail2; | 246 | goto fail2; |
258 | } | 247 | } |
259 | 248 | ||
260 | if (port->line) { | ||
261 | if (peripheral_request_list(bfin_uart_pin_req_sport1, DRV_NAME)) | ||
262 | goto fail3; | ||
263 | } else { | ||
264 | if (peripheral_request_list(bfin_uart_pin_req_sport0, DRV_NAME)) | ||
265 | goto fail3; | ||
266 | } | ||
267 | |||
268 | sport_uart_setup(up, get_sclk(), port->uartclk); | ||
269 | |||
270 | /* Enable receive interrupt */ | ||
271 | SPORT_PUT_RCR1(up, (SPORT_GET_RCR1(up) | RSPEN)); | ||
272 | SSYNC(); | ||
273 | |||
274 | return 0; | 249 | return 0; |
250 | fail2: | ||
251 | free_irq(up->port.irq+1, up); | ||
252 | fail1: | ||
253 | free_irq(up->port.irq, up); | ||
275 | 254 | ||
276 | 255 | return ret; | |
277 | fail3: | ||
278 | printk(KERN_ERR DRV_NAME | ||
279 | ": Requesting Peripherals failed\n"); | ||
280 | |||
281 | free_irq(up->err_irq, up); | ||
282 | fail2: | ||
283 | free_irq(up->tx_irq, up); | ||
284 | fail1: | ||
285 | free_irq(up->rx_irq, up); | ||
286 | |||
287 | return retval; | ||
288 | |||
289 | } | 256 | } |
290 | 257 | ||
291 | static void sport_uart_tx_chars(struct sport_uart_port *up) | 258 | static void sport_uart_tx_chars(struct sport_uart_port *up) |
@@ -344,20 +311,17 @@ static void sport_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
344 | static void sport_stop_tx(struct uart_port *port) | 311 | static void sport_stop_tx(struct uart_port *port) |
345 | { | 312 | { |
346 | struct sport_uart_port *up = (struct sport_uart_port *)port; | 313 | struct sport_uart_port *up = (struct sport_uart_port *)port; |
347 | unsigned int stat; | ||
348 | 314 | ||
349 | pr_debug("%s enter\n", __func__); | 315 | pr_debug("%s enter\n", __func__); |
350 | 316 | ||
351 | stat = SPORT_GET_STAT(up); | ||
352 | while(!(stat & TXHRE)) { | ||
353 | udelay(1); | ||
354 | stat = SPORT_GET_STAT(up); | ||
355 | } | ||
356 | /* Although the hold register is empty, last byte is still in shift | 317 | /* Although the hold register is empty, last byte is still in shift |
357 | * register and not sent out yet. If baud rate is lower than default, | 318 | * register and not sent out yet. So, put a dummy data into TX FIFO. |
358 | * delay should be longer. For example, if the baud rate is 9600, | 319 | * Then, sport tx stops when last byte is shift out and the dummy |
359 | * the delay must be at least 2ms by experience */ | 320 | * data is moved into the shift register. |
360 | udelay(500); | 321 | */ |
322 | SPORT_PUT_TX(up, 0xffff); | ||
323 | while (!(SPORT_GET_STAT(up) & TXHRE)) | ||
324 | cpu_relax(); | ||
361 | 325 | ||
362 | SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) & ~TSPEN)); | 326 | SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) & ~TSPEN)); |
363 | SSYNC(); | 327 | SSYNC(); |
@@ -370,6 +334,7 @@ static void sport_start_tx(struct uart_port *port) | |||
370 | struct sport_uart_port *up = (struct sport_uart_port *)port; | 334 | struct sport_uart_port *up = (struct sport_uart_port *)port; |
371 | 335 | ||
372 | pr_debug("%s enter\n", __func__); | 336 | pr_debug("%s enter\n", __func__); |
337 | |||
373 | /* Write data into SPORT FIFO before enable SPROT to transmit */ | 338 | /* Write data into SPORT FIFO before enable SPROT to transmit */ |
374 | sport_uart_tx_chars(up); | 339 | sport_uart_tx_chars(up); |
375 | 340 | ||
@@ -403,37 +368,24 @@ static void sport_shutdown(struct uart_port *port) | |||
403 | { | 368 | { |
404 | struct sport_uart_port *up = (struct sport_uart_port *)port; | 369 | struct sport_uart_port *up = (struct sport_uart_port *)port; |
405 | 370 | ||
406 | pr_debug("%s enter\n", __func__); | 371 | dev_dbg(port->dev, "%s enter\n", __func__); |
407 | 372 | ||
408 | /* Disable sport */ | 373 | /* Disable sport */ |
409 | SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) & ~TSPEN)); | 374 | SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) & ~TSPEN)); |
410 | SPORT_PUT_RCR1(up, (SPORT_GET_RCR1(up) & ~RSPEN)); | 375 | SPORT_PUT_RCR1(up, (SPORT_GET_RCR1(up) & ~RSPEN)); |
411 | SSYNC(); | 376 | SSYNC(); |
412 | 377 | ||
413 | if (port->line) { | 378 | free_irq(up->port.irq, up); |
414 | peripheral_free_list(bfin_uart_pin_req_sport1); | 379 | free_irq(up->port.irq+1, up); |
415 | } else { | ||
416 | peripheral_free_list(bfin_uart_pin_req_sport0); | ||
417 | } | ||
418 | |||
419 | free_irq(up->rx_irq, up); | ||
420 | free_irq(up->tx_irq, up); | ||
421 | free_irq(up->err_irq, up); | 380 | free_irq(up->err_irq, up); |
422 | } | 381 | } |
423 | 382 | ||
424 | static void sport_set_termios(struct uart_port *port, | ||
425 | struct ktermios *termios, struct ktermios *old) | ||
426 | { | ||
427 | pr_debug("%s enter, c_cflag:%08x\n", __func__, termios->c_cflag); | ||
428 | uart_update_timeout(port, CS8 ,port->uartclk); | ||
429 | } | ||
430 | |||
431 | static const char *sport_type(struct uart_port *port) | 383 | static const char *sport_type(struct uart_port *port) |
432 | { | 384 | { |
433 | struct sport_uart_port *up = (struct sport_uart_port *)port; | 385 | struct sport_uart_port *up = (struct sport_uart_port *)port; |
434 | 386 | ||
435 | pr_debug("%s enter\n", __func__); | 387 | pr_debug("%s enter\n", __func__); |
436 | return up->name; | 388 | return up->port.type == PORT_BFIN_SPORT ? "BFIN-SPORT-UART" : NULL; |
437 | } | 389 | } |
438 | 390 | ||
439 | static void sport_release_port(struct uart_port *port) | 391 | static void sport_release_port(struct uart_port *port) |
@@ -461,6 +413,110 @@ static int sport_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
461 | return 0; | 413 | return 0; |
462 | } | 414 | } |
463 | 415 | ||
416 | static void sport_set_termios(struct uart_port *port, | ||
417 | struct ktermios *termios, struct ktermios *old) | ||
418 | { | ||
419 | struct sport_uart_port *up = (struct sport_uart_port *)port; | ||
420 | unsigned long flags; | ||
421 | int i; | ||
422 | |||
423 | pr_debug("%s enter, c_cflag:%08x\n", __func__, termios->c_cflag); | ||
424 | |||
425 | switch (termios->c_cflag & CSIZE) { | ||
426 | case CS8: | ||
427 | up->csize = 8; | ||
428 | break; | ||
429 | case CS7: | ||
430 | up->csize = 7; | ||
431 | break; | ||
432 | case CS6: | ||
433 | up->csize = 6; | ||
434 | break; | ||
435 | case CS5: | ||
436 | up->csize = 5; | ||
437 | break; | ||
438 | default: | ||
439 | pr_warning("requested word length not supported\n"); | ||
440 | } | ||
441 | |||
442 | if (termios->c_cflag & CSTOPB) { | ||
443 | up->stopb = 1; | ||
444 | } | ||
445 | if (termios->c_cflag & PARENB) { | ||
446 | pr_warning("PAREN bits is not supported yet\n"); | ||
447 | /* up->parib = 1; */ | ||
448 | } | ||
449 | |||
450 | port->read_status_mask = OE; | ||
451 | if (termios->c_iflag & INPCK) | ||
452 | port->read_status_mask |= (FE | PE); | ||
453 | if (termios->c_iflag & (BRKINT | PARMRK)) | ||
454 | port->read_status_mask |= BI; | ||
455 | |||
456 | /* | ||
457 | * Characters to ignore | ||
458 | */ | ||
459 | port->ignore_status_mask = 0; | ||
460 | if (termios->c_iflag & IGNPAR) | ||
461 | port->ignore_status_mask |= FE | PE; | ||
462 | if (termios->c_iflag & IGNBRK) { | ||
463 | port->ignore_status_mask |= BI; | ||
464 | /* | ||
465 | * If we're ignoring parity and break indicators, | ||
466 | * ignore overruns too (for real raw support). | ||
467 | */ | ||
468 | if (termios->c_iflag & IGNPAR) | ||
469 | port->ignore_status_mask |= OE; | ||
470 | } | ||
471 | |||
472 | /* RX extract mask */ | ||
473 | up->rxmask = 0x01 | (((up->csize + up->stopb) * 2 - 1) << 0x8); | ||
474 | /* TX masks, 8 bit data and 1 bit stop for example: | ||
475 | * mask1 = b#0111111110 | ||
476 | * mask2 = b#1000000000 | ||
477 | */ | ||
478 | for (i = 0, up->txmask1 = 0; i < up->csize; i++) | ||
479 | up->txmask1 |= (1<<i); | ||
480 | up->txmask2 = (1<<i); | ||
481 | if (up->stopb) { | ||
482 | ++i; | ||
483 | up->txmask2 |= (1<<i); | ||
484 | } | ||
485 | up->txmask1 <<= 1; | ||
486 | up->txmask2 <<= 1; | ||
487 | /* uart baud rate */ | ||
488 | port->uartclk = uart_get_baud_rate(port, termios, old, 0, get_sclk()/16); | ||
489 | |||
490 | spin_lock_irqsave(&up->port.lock, flags); | ||
491 | |||
492 | /* Disable UART */ | ||
493 | SPORT_PUT_TCR1(up, SPORT_GET_TCR1(up) & ~TSPEN); | ||
494 | SPORT_PUT_RCR1(up, SPORT_GET_RCR1(up) & ~RSPEN); | ||
495 | |||
496 | sport_uart_setup(up, up->csize + up->stopb, port->uartclk); | ||
497 | |||
498 | /* driver TX line high after config, one dummy data is | ||
499 | * necessary to stop sport after shift one byte | ||
500 | */ | ||
501 | SPORT_PUT_TX(up, 0xffff); | ||
502 | SPORT_PUT_TX(up, 0xffff); | ||
503 | SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) | TSPEN)); | ||
504 | SSYNC(); | ||
505 | while (!(SPORT_GET_STAT(up) & TXHRE)) | ||
506 | cpu_relax(); | ||
507 | SPORT_PUT_TCR1(up, SPORT_GET_TCR1(up) & ~TSPEN); | ||
508 | SSYNC(); | ||
509 | |||
510 | /* Port speed changed, update the per-port timeout. */ | ||
511 | uart_update_timeout(port, termios->c_cflag, port->uartclk); | ||
512 | |||
513 | /* Enable sport rx */ | ||
514 | SPORT_PUT_RCR1(up, SPORT_GET_RCR1(up) | RSPEN); | ||
515 | SSYNC(); | ||
516 | |||
517 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
518 | } | ||
519 | |||
464 | struct uart_ops sport_uart_ops = { | 520 | struct uart_ops sport_uart_ops = { |
465 | .tx_empty = sport_tx_empty, | 521 | .tx_empty = sport_tx_empty, |
466 | .set_mctrl = sport_set_mctrl, | 522 | .set_mctrl = sport_set_mctrl, |
@@ -480,138 +536,319 @@ struct uart_ops sport_uart_ops = { | |||
480 | .verify_port = sport_verify_port, | 536 | .verify_port = sport_verify_port, |
481 | }; | 537 | }; |
482 | 538 | ||
483 | static struct sport_uart_port sport_uart_ports[] = { | 539 | #define BFIN_SPORT_UART_MAX_PORTS 4 |
484 | { /* SPORT 0 */ | 540 | |
485 | .name = "SPORT0", | 541 | static struct sport_uart_port *bfin_sport_uart_ports[BFIN_SPORT_UART_MAX_PORTS]; |
486 | .tx_irq = IRQ_SPORT0_TX, | 542 | |
487 | .rx_irq = IRQ_SPORT0_RX, | 543 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE |
488 | .err_irq= IRQ_SPORT0_ERROR, | 544 | static int __init |
489 | .port = { | 545 | sport_uart_console_setup(struct console *co, char *options) |
490 | .type = PORT_BFIN_SPORT, | 546 | { |
491 | .iotype = UPIO_MEM, | 547 | struct sport_uart_port *up; |
492 | .membase = (void __iomem *)SPORT0_TCR1, | 548 | int baud = 57600; |
493 | .mapbase = SPORT0_TCR1, | 549 | int bits = 8; |
494 | .irq = IRQ_SPORT0_RX, | 550 | int parity = 'n'; |
495 | .uartclk = CONFIG_SPORT_BAUD_RATE, | 551 | int flow = 'n'; |
496 | .fifosize = 8, | 552 | |
497 | .ops = &sport_uart_ops, | 553 | /* Check whether an invalid uart number has been specified */ |
498 | .line = 0, | 554 | if (co->index < 0 || co->index >= BFIN_SPORT_UART_MAX_PORTS) |
499 | }, | 555 | return -ENODEV; |
500 | }, { /* SPORT 1 */ | 556 | |
501 | .name = "SPORT1", | 557 | up = bfin_sport_uart_ports[co->index]; |
502 | .tx_irq = IRQ_SPORT1_TX, | 558 | if (!up) |
503 | .rx_irq = IRQ_SPORT1_RX, | 559 | return -ENODEV; |
504 | .err_irq= IRQ_SPORT1_ERROR, | 560 | |
505 | .port = { | 561 | if (options) |
506 | .type = PORT_BFIN_SPORT, | 562 | uart_parse_options(options, &baud, &parity, &bits, &flow); |
507 | .iotype = UPIO_MEM, | 563 | |
508 | .membase = (void __iomem *)SPORT1_TCR1, | 564 | return uart_set_options(&up->port, co, baud, parity, bits, flow); |
509 | .mapbase = SPORT1_TCR1, | 565 | } |
510 | .irq = IRQ_SPORT1_RX, | 566 | |
511 | .uartclk = CONFIG_SPORT_BAUD_RATE, | 567 | static void sport_uart_console_putchar(struct uart_port *port, int ch) |
512 | .fifosize = 8, | 568 | { |
513 | .ops = &sport_uart_ops, | 569 | struct sport_uart_port *up = (struct sport_uart_port *)port; |
514 | .line = 1, | 570 | |
515 | }, | 571 | while (SPORT_GET_STAT(up) & TXF) |
572 | barrier(); | ||
573 | |||
574 | tx_one_byte(up, ch); | ||
575 | } | ||
576 | |||
577 | /* | ||
578 | * Interrupts are disabled on entering | ||
579 | */ | ||
580 | static void | ||
581 | sport_uart_console_write(struct console *co, const char *s, unsigned int count) | ||
582 | { | ||
583 | struct sport_uart_port *up = bfin_sport_uart_ports[co->index]; | ||
584 | unsigned long flags; | ||
585 | |||
586 | spin_lock_irqsave(&up->port.lock, flags); | ||
587 | |||
588 | if (SPORT_GET_TCR1(up) & TSPEN) | ||
589 | uart_console_write(&up->port, s, count, sport_uart_console_putchar); | ||
590 | else { | ||
591 | /* dummy data to start sport */ | ||
592 | while (SPORT_GET_STAT(up) & TXF) | ||
593 | barrier(); | ||
594 | SPORT_PUT_TX(up, 0xffff); | ||
595 | /* Enable transmit, then an interrupt will generated */ | ||
596 | SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) | TSPEN)); | ||
597 | SSYNC(); | ||
598 | |||
599 | uart_console_write(&up->port, s, count, sport_uart_console_putchar); | ||
600 | |||
601 | /* Although the hold register is empty, last byte is still in shift | ||
602 | * register and not sent out yet. So, put a dummy data into TX FIFO. | ||
603 | * Then, sport tx stops when last byte is shift out and the dummy | ||
604 | * data is moved into the shift register. | ||
605 | */ | ||
606 | while (SPORT_GET_STAT(up) & TXF) | ||
607 | barrier(); | ||
608 | SPORT_PUT_TX(up, 0xffff); | ||
609 | while (!(SPORT_GET_STAT(up) & TXHRE)) | ||
610 | barrier(); | ||
611 | |||
612 | /* Stop sport tx transfer */ | ||
613 | SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) & ~TSPEN)); | ||
614 | SSYNC(); | ||
516 | } | 615 | } |
616 | |||
617 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
618 | } | ||
619 | |||
620 | static struct uart_driver sport_uart_reg; | ||
621 | |||
622 | static struct console sport_uart_console = { | ||
623 | .name = DEVICE_NAME, | ||
624 | .write = sport_uart_console_write, | ||
625 | .device = uart_console_device, | ||
626 | .setup = sport_uart_console_setup, | ||
627 | .flags = CON_PRINTBUFFER, | ||
628 | .index = -1, | ||
629 | .data = &sport_uart_reg, | ||
517 | }; | 630 | }; |
518 | 631 | ||
632 | #define SPORT_UART_CONSOLE (&sport_uart_console) | ||
633 | #else | ||
634 | #define SPORT_UART_CONSOLE NULL | ||
635 | #endif /* CONFIG_SERIAL_BFIN_SPORT_CONSOLE */ | ||
636 | |||
637 | |||
519 | static struct uart_driver sport_uart_reg = { | 638 | static struct uart_driver sport_uart_reg = { |
520 | .owner = THIS_MODULE, | 639 | .owner = THIS_MODULE, |
521 | .driver_name = "SPORT-UART", | 640 | .driver_name = DRV_NAME, |
522 | .dev_name = "ttySS", | 641 | .dev_name = DEVICE_NAME, |
523 | .major = 204, | 642 | .major = 204, |
524 | .minor = 84, | 643 | .minor = 84, |
525 | .nr = ARRAY_SIZE(sport_uart_ports), | 644 | .nr = BFIN_SPORT_UART_MAX_PORTS, |
526 | .cons = NULL, | 645 | .cons = SPORT_UART_CONSOLE, |
527 | }; | 646 | }; |
528 | 647 | ||
529 | static int sport_uart_suspend(struct platform_device *dev, pm_message_t state) | 648 | #ifdef CONFIG_PM |
649 | static int sport_uart_suspend(struct device *dev) | ||
530 | { | 650 | { |
531 | struct sport_uart_port *sport = platform_get_drvdata(dev); | 651 | struct sport_uart_port *sport = dev_get_drvdata(dev); |
532 | 652 | ||
533 | pr_debug("%s enter\n", __func__); | 653 | dev_dbg(dev, "%s enter\n", __func__); |
534 | if (sport) | 654 | if (sport) |
535 | uart_suspend_port(&sport_uart_reg, &sport->port); | 655 | uart_suspend_port(&sport_uart_reg, &sport->port); |
536 | 656 | ||
537 | return 0; | 657 | return 0; |
538 | } | 658 | } |
539 | 659 | ||
540 | static int sport_uart_resume(struct platform_device *dev) | 660 | static int sport_uart_resume(struct device *dev) |
541 | { | 661 | { |
542 | struct sport_uart_port *sport = platform_get_drvdata(dev); | 662 | struct sport_uart_port *sport = dev_get_drvdata(dev); |
543 | 663 | ||
544 | pr_debug("%s enter\n", __func__); | 664 | dev_dbg(dev, "%s enter\n", __func__); |
545 | if (sport) | 665 | if (sport) |
546 | uart_resume_port(&sport_uart_reg, &sport->port); | 666 | uart_resume_port(&sport_uart_reg, &sport->port); |
547 | 667 | ||
548 | return 0; | 668 | return 0; |
549 | } | 669 | } |
550 | 670 | ||
551 | static int sport_uart_probe(struct platform_device *dev) | 671 | static struct dev_pm_ops bfin_sport_uart_dev_pm_ops = { |
672 | .suspend = sport_uart_suspend, | ||
673 | .resume = sport_uart_resume, | ||
674 | }; | ||
675 | #endif | ||
676 | |||
677 | static int __devinit sport_uart_probe(struct platform_device *pdev) | ||
552 | { | 678 | { |
553 | pr_debug("%s enter\n", __func__); | 679 | struct resource *res; |
554 | sport_uart_ports[dev->id].port.dev = &dev->dev; | 680 | struct sport_uart_port *sport; |
555 | uart_add_one_port(&sport_uart_reg, &sport_uart_ports[dev->id].port); | 681 | int ret = 0; |
556 | platform_set_drvdata(dev, &sport_uart_ports[dev->id]); | ||
557 | 682 | ||
558 | return 0; | 683 | dev_dbg(&pdev->dev, "%s enter\n", __func__); |
684 | |||
685 | if (pdev->id < 0 || pdev->id >= BFIN_SPORT_UART_MAX_PORTS) { | ||
686 | dev_err(&pdev->dev, "Wrong sport uart platform device id.\n"); | ||
687 | return -ENOENT; | ||
688 | } | ||
689 | |||
690 | if (bfin_sport_uart_ports[pdev->id] == NULL) { | ||
691 | bfin_sport_uart_ports[pdev->id] = | ||
692 | kmalloc(sizeof(struct sport_uart_port), GFP_KERNEL); | ||
693 | sport = bfin_sport_uart_ports[pdev->id]; | ||
694 | if (!sport) { | ||
695 | dev_err(&pdev->dev, | ||
696 | "Fail to kmalloc sport_uart_port\n"); | ||
697 | return -ENOMEM; | ||
698 | } | ||
699 | |||
700 | ret = peripheral_request_list( | ||
701 | (unsigned short *)pdev->dev.platform_data, DRV_NAME); | ||
702 | if (ret) { | ||
703 | dev_err(&pdev->dev, | ||
704 | "Fail to request SPORT peripherals\n"); | ||
705 | goto out_error_free_mem; | ||
706 | } | ||
707 | |||
708 | spin_lock_init(&sport->port.lock); | ||
709 | sport->port.fifosize = SPORT_TX_FIFO_SIZE, | ||
710 | sport->port.ops = &sport_uart_ops; | ||
711 | sport->port.line = pdev->id; | ||
712 | sport->port.iotype = UPIO_MEM; | ||
713 | sport->port.flags = UPF_BOOT_AUTOCONF; | ||
714 | |||
715 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
716 | if (res == NULL) { | ||
717 | dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n"); | ||
718 | ret = -ENOENT; | ||
719 | goto out_error_free_peripherals; | ||
720 | } | ||
721 | |||
722 | sport->port.membase = ioremap(res->start, | ||
723 | res->end - res->start); | ||
724 | if (!sport->port.membase) { | ||
725 | dev_err(&pdev->dev, "Cannot map sport IO\n"); | ||
726 | ret = -ENXIO; | ||
727 | goto out_error_free_peripherals; | ||
728 | } | ||
729 | |||
730 | sport->port.irq = platform_get_irq(pdev, 0); | ||
731 | if (sport->port.irq < 0) { | ||
732 | dev_err(&pdev->dev, "No sport RX/TX IRQ specified\n"); | ||
733 | ret = -ENOENT; | ||
734 | goto out_error_unmap; | ||
735 | } | ||
736 | |||
737 | sport->err_irq = platform_get_irq(pdev, 1); | ||
738 | if (sport->err_irq < 0) { | ||
739 | dev_err(&pdev->dev, "No sport status IRQ specified\n"); | ||
740 | ret = -ENOENT; | ||
741 | goto out_error_unmap; | ||
742 | } | ||
743 | } | ||
744 | |||
745 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE | ||
746 | if (!is_early_platform_device(pdev)) { | ||
747 | #endif | ||
748 | sport = bfin_sport_uart_ports[pdev->id]; | ||
749 | sport->port.dev = &pdev->dev; | ||
750 | dev_set_drvdata(&pdev->dev, sport); | ||
751 | ret = uart_add_one_port(&sport_uart_reg, &sport->port); | ||
752 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE | ||
753 | } | ||
754 | #endif | ||
755 | if (!ret) | ||
756 | return 0; | ||
757 | |||
758 | if (sport) { | ||
759 | out_error_unmap: | ||
760 | iounmap(sport->port.membase); | ||
761 | out_error_free_peripherals: | ||
762 | peripheral_free_list( | ||
763 | (unsigned short *)pdev->dev.platform_data); | ||
764 | out_error_free_mem: | ||
765 | kfree(sport); | ||
766 | bfin_sport_uart_ports[pdev->id] = NULL; | ||
767 | } | ||
768 | |||
769 | return ret; | ||
559 | } | 770 | } |
560 | 771 | ||
561 | static int sport_uart_remove(struct platform_device *dev) | 772 | static int __devexit sport_uart_remove(struct platform_device *pdev) |
562 | { | 773 | { |
563 | struct sport_uart_port *sport = platform_get_drvdata(dev); | 774 | struct sport_uart_port *sport = platform_get_drvdata(pdev); |
564 | 775 | ||
565 | pr_debug("%s enter\n", __func__); | 776 | dev_dbg(&pdev->dev, "%s enter\n", __func__); |
566 | platform_set_drvdata(dev, NULL); | 777 | dev_set_drvdata(&pdev->dev, NULL); |
567 | 778 | ||
568 | if (sport) | 779 | if (sport) { |
569 | uart_remove_one_port(&sport_uart_reg, &sport->port); | 780 | uart_remove_one_port(&sport_uart_reg, &sport->port); |
781 | iounmap(sport->port.membase); | ||
782 | peripheral_free_list( | ||
783 | (unsigned short *)pdev->dev.platform_data); | ||
784 | kfree(sport); | ||
785 | bfin_sport_uart_ports[pdev->id] = NULL; | ||
786 | } | ||
570 | 787 | ||
571 | return 0; | 788 | return 0; |
572 | } | 789 | } |
573 | 790 | ||
574 | static struct platform_driver sport_uart_driver = { | 791 | static struct platform_driver sport_uart_driver = { |
575 | .probe = sport_uart_probe, | 792 | .probe = sport_uart_probe, |
576 | .remove = sport_uart_remove, | 793 | .remove = __devexit_p(sport_uart_remove), |
577 | .suspend = sport_uart_suspend, | ||
578 | .resume = sport_uart_resume, | ||
579 | .driver = { | 794 | .driver = { |
580 | .name = DRV_NAME, | 795 | .name = DRV_NAME, |
796 | #ifdef CONFIG_PM | ||
797 | .pm = &bfin_sport_uart_dev_pm_ops, | ||
798 | #endif | ||
581 | }, | 799 | }, |
582 | }; | 800 | }; |
583 | 801 | ||
802 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE | ||
803 | static __initdata struct early_platform_driver early_sport_uart_driver = { | ||
804 | .class_str = DRV_NAME, | ||
805 | .pdrv = &sport_uart_driver, | ||
806 | .requested_id = EARLY_PLATFORM_ID_UNSET, | ||
807 | }; | ||
808 | |||
809 | static int __init sport_uart_rs_console_init(void) | ||
810 | { | ||
811 | early_platform_driver_register(&early_sport_uart_driver, DRV_NAME); | ||
812 | |||
813 | early_platform_driver_probe(DRV_NAME, BFIN_SPORT_UART_MAX_PORTS, 0); | ||
814 | |||
815 | register_console(&sport_uart_console); | ||
816 | |||
817 | return 0; | ||
818 | } | ||
819 | console_initcall(sport_uart_rs_console_init); | ||
820 | #endif | ||
821 | |||
584 | static int __init sport_uart_init(void) | 822 | static int __init sport_uart_init(void) |
585 | { | 823 | { |
586 | int ret; | 824 | int ret; |
587 | 825 | ||
588 | pr_debug("%s enter\n", __func__); | 826 | pr_info("Serial: Blackfin uart over sport driver\n"); |
827 | |||
589 | ret = uart_register_driver(&sport_uart_reg); | 828 | ret = uart_register_driver(&sport_uart_reg); |
590 | if (ret != 0) { | 829 | if (ret) { |
591 | printk(KERN_ERR "Failed to register %s:%d\n", | 830 | pr_err("failed to register %s:%d\n", |
592 | sport_uart_reg.driver_name, ret); | 831 | sport_uart_reg.driver_name, ret); |
593 | return ret; | 832 | return ret; |
594 | } | 833 | } |
595 | 834 | ||
596 | ret = platform_driver_register(&sport_uart_driver); | 835 | ret = platform_driver_register(&sport_uart_driver); |
597 | if (ret != 0) { | 836 | if (ret) { |
598 | printk(KERN_ERR "Failed to register sport uart driver:%d\n", ret); | 837 | pr_err("failed to register sport uart driver:%d\n", ret); |
599 | uart_unregister_driver(&sport_uart_reg); | 838 | uart_unregister_driver(&sport_uart_reg); |
600 | } | 839 | } |
601 | 840 | ||
602 | |||
603 | pr_debug("%s exit\n", __func__); | ||
604 | return ret; | 841 | return ret; |
605 | } | 842 | } |
843 | module_init(sport_uart_init); | ||
606 | 844 | ||
607 | static void __exit sport_uart_exit(void) | 845 | static void __exit sport_uart_exit(void) |
608 | { | 846 | { |
609 | pr_debug("%s enter\n", __func__); | ||
610 | platform_driver_unregister(&sport_uart_driver); | 847 | platform_driver_unregister(&sport_uart_driver); |
611 | uart_unregister_driver(&sport_uart_reg); | 848 | uart_unregister_driver(&sport_uart_reg); |
612 | } | 849 | } |
613 | |||
614 | module_init(sport_uart_init); | ||
615 | module_exit(sport_uart_exit); | 850 | module_exit(sport_uart_exit); |
616 | 851 | ||
852 | MODULE_AUTHOR("Sonic Zhang, Roy Huang"); | ||
853 | MODULE_DESCRIPTION("Blackfin serial over SPORT driver"); | ||
617 | MODULE_LICENSE("GPL"); | 854 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/serial/bfin_sport_uart.h b/drivers/serial/bfin_sport_uart.h index 671d41cc1a3f..abe03614e4df 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 | ||
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 | ||
11 | /* | ||
12 | * This driver and the hardware supported are in term of EE-191 of ADI. | ||
13 | * http://www.analog.com/UploadedFiles/Application_Notes/399447663EE191.pdf | ||
14 | * This application note describe how to implement a UART on a Sharc DSP, | ||
15 | * but this driver is implemented on Blackfin Processor. | ||
16 | * Transmit Frame Sync is not used by this driver to transfer data out. | ||
17 | */ | ||
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 */ |
@@ -61,3 +55,7 @@ | |||
61 | #define SPORT_PUT_RCLKDIV(sport, v) bfin_write16(((sport)->port.membase + OFFSET_RCLKDIV), v) | 55 | #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) | 56 | #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) | 57 | #define SPORT_PUT_STAT(sport, v) bfin_write16(((sport)->port.membase + OFFSET_STAT), v) |
58 | |||
59 | #define SPORT_TX_FIFO_SIZE 8 | ||
60 | |||
61 | #endif /* _BFIN_SPORT_UART_H */ | ||
diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c index 0028b6f89ce6..53a468227056 100644 --- a/drivers/serial/icom.c +++ b/drivers/serial/icom.c | |||
@@ -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); |
@@ -1654,4 +1653,6 @@ MODULE_DESCRIPTION("IBM iSeries Serial IOA driver"); | |||
1654 | MODULE_SUPPORTED_DEVICE | 1653 | MODULE_SUPPORTED_DEVICE |
1655 | ("IBM iSeries 2745, 2771, 2772, 2742, 2793 and 2805 Communications adapters"); | 1654 | ("IBM iSeries 2745, 2771, 2772, 2742, 2793 and 2805 Communications adapters"); |
1656 | MODULE_LICENSE("GPL"); | 1655 | MODULE_LICENSE("GPL"); |
1657 | 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/imx.c b/drivers/serial/imx.c index b801f5ab2b7b..e579d7a1807a 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c | |||
@@ -1279,7 +1279,7 @@ static int serial_imx_probe(struct platform_device *pdev) | |||
1279 | sport->use_irda = 1; | 1279 | sport->use_irda = 1; |
1280 | #endif | 1280 | #endif |
1281 | 1281 | ||
1282 | if (pdata->init) { | 1282 | if (pdata && pdata->init) { |
1283 | ret = pdata->init(pdev); | 1283 | ret = pdata->init(pdev); |
1284 | if (ret) | 1284 | if (ret) |
1285 | goto clkput; | 1285 | goto clkput; |
@@ -1292,7 +1292,7 @@ static int serial_imx_probe(struct platform_device *pdev) | |||
1292 | 1292 | ||
1293 | return 0; | 1293 | return 0; |
1294 | deinit: | 1294 | deinit: |
1295 | if (pdata->exit) | 1295 | if (pdata && pdata->exit) |
1296 | pdata->exit(pdev); | 1296 | pdata->exit(pdev); |
1297 | clkput: | 1297 | clkput: |
1298 | clk_put(sport->clk); | 1298 | clk_put(sport->clk); |
@@ -1321,7 +1321,7 @@ static int serial_imx_remove(struct platform_device *pdev) | |||
1321 | 1321 | ||
1322 | clk_disable(sport->clk); | 1322 | clk_disable(sport->clk); |
1323 | 1323 | ||
1324 | if (pdata->exit) | 1324 | if (pdata && pdata->exit) |
1325 | pdata->exit(pdev); | 1325 | pdata->exit(pdev); |
1326 | 1326 | ||
1327 | iounmap(sport->port.membase); | 1327 | iounmap(sport->port.membase); |
diff --git a/drivers/serial/ioc3_serial.c b/drivers/serial/ioc3_serial.c index 85dc0410ac1a..23ba6b40b3ac 100644 --- a/drivers/serial/ioc3_serial.c +++ b/drivers/serial/ioc3_serial.c | |||
@@ -1411,8 +1411,7 @@ static int receive_chars(struct uart_port *the_port) | |||
1411 | read_count = do_read(the_port, ch, MAX_CHARS); | 1411 | read_count = do_read(the_port, ch, MAX_CHARS); |
1412 | if (read_count > 0) { | 1412 | if (read_count > 0) { |
1413 | flip = 1; | 1413 | flip = 1; |
1414 | read_room = tty_buffer_request_room(tty, read_count); | 1414 | 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; | 1415 | the_port->icount.rx += read_count; |
1417 | } | 1416 | } |
1418 | spin_unlock_irqrestore(&the_port->lock, pflags); | 1417 | spin_unlock_irqrestore(&the_port->lock, pflags); |
diff --git a/drivers/serial/jsm/jsm_driver.c b/drivers/serial/jsm/jsm_driver.c index 108c3e0471fd..12cb5e446a4f 100644 --- a/drivers/serial/jsm/jsm_driver.c +++ b/drivers/serial/jsm/jsm_driver.c | |||
@@ -179,6 +179,7 @@ static int __devinit jsm_probe_one(struct pci_dev *pdev, const struct pci_device | |||
179 | 179 | ||
180 | return 0; | 180 | return 0; |
181 | out_free_irq: | 181 | out_free_irq: |
182 | jsm_remove_uart_port(brd); | ||
182 | free_irq(brd->irq, brd); | 183 | free_irq(brd->irq, brd); |
183 | out_iounmap: | 184 | out_iounmap: |
184 | iounmap(brd->re_map_membase); | 185 | iounmap(brd->re_map_membase); |
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c index cd95e215550d..5673ca9dfdc8 100644 --- a/drivers/serial/jsm/jsm_tty.c +++ b/drivers/serial/jsm/jsm_tty.c | |||
@@ -432,7 +432,7 @@ int __devinit jsm_tty_init(struct jsm_board *brd) | |||
432 | 432 | ||
433 | int jsm_uart_port_init(struct jsm_board *brd) | 433 | int jsm_uart_port_init(struct jsm_board *brd) |
434 | { | 434 | { |
435 | int i; | 435 | int i, rc; |
436 | unsigned int line; | 436 | unsigned int line; |
437 | struct jsm_channel *ch; | 437 | struct jsm_channel *ch; |
438 | 438 | ||
@@ -467,8 +467,11 @@ int jsm_uart_port_init(struct jsm_board *brd) | |||
467 | } else | 467 | } else |
468 | set_bit(line, linemap); | 468 | set_bit(line, linemap); |
469 | brd->channels[i]->uart_port.line = line; | 469 | brd->channels[i]->uart_port.line = line; |
470 | if (uart_add_one_port (&jsm_uart_driver, &brd->channels[i]->uart_port)) | 470 | rc = uart_add_one_port (&jsm_uart_driver, &brd->channels[i]->uart_port); |
471 | printk(KERN_INFO "jsm: add device failed\n"); | 471 | if (rc){ |
472 | printk(KERN_INFO "jsm: Port %d failed. Aborting...\n", i); | ||
473 | return rc; | ||
474 | } | ||
472 | else | 475 | else |
473 | printk(KERN_INFO "jsm: Port %d added\n", i); | 476 | printk(KERN_INFO "jsm: Port %d added\n", i); |
474 | } | 477 | } |
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index 7ce9e9f567a3..3119fddaedb5 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c | |||
@@ -74,6 +74,7 @@ | |||
74 | #include <linux/io.h> | 74 | #include <linux/io.h> |
75 | #include <linux/of.h> | 75 | #include <linux/of.h> |
76 | #include <linux/of_platform.h> | 76 | #include <linux/of_platform.h> |
77 | #include <linux/clk.h> | ||
77 | 78 | ||
78 | #include <asm/mpc52xx.h> | 79 | #include <asm/mpc52xx.h> |
79 | #include <asm/mpc52xx_psc.h> | 80 | #include <asm/mpc52xx_psc.h> |
@@ -113,6 +114,7 @@ static void mpc52xx_uart_of_enumerate(void); | |||
113 | 114 | ||
114 | /* Forward declaration of the interruption handling routine */ | 115 | /* Forward declaration of the interruption handling routine */ |
115 | static irqreturn_t mpc52xx_uart_int(int irq, void *dev_id); | 116 | static irqreturn_t mpc52xx_uart_int(int irq, void *dev_id); |
117 | static irqreturn_t mpc5xxx_uart_process_int(struct uart_port *port); | ||
116 | 118 | ||
117 | 119 | ||
118 | /* Simple macro to test if a port is console or not. This one is taken | 120 | /* Simple macro to test if a port is console or not. This one is taken |
@@ -145,6 +147,11 @@ struct psc_ops { | |||
145 | void (*cw_disable_ints)(struct uart_port *port); | 147 | void (*cw_disable_ints)(struct uart_port *port); |
146 | void (*cw_restore_ints)(struct uart_port *port); | 148 | void (*cw_restore_ints)(struct uart_port *port); |
147 | unsigned long (*getuartclk)(void *p); | 149 | unsigned long (*getuartclk)(void *p); |
150 | int (*clock)(struct uart_port *port, int enable); | ||
151 | int (*fifoc_init)(void); | ||
152 | void (*fifoc_uninit)(void); | ||
153 | void (*get_irq)(struct uart_port *, struct device_node *); | ||
154 | irqreturn_t (*handle_irq)(struct uart_port *port); | ||
148 | }; | 155 | }; |
149 | 156 | ||
150 | #ifdef CONFIG_PPC_MPC52xx | 157 | #ifdef CONFIG_PPC_MPC52xx |
@@ -256,6 +263,18 @@ static unsigned long mpc52xx_getuartclk(void *p) | |||
256 | return mpc5xxx_get_bus_frequency(p) / 2; | 263 | return mpc5xxx_get_bus_frequency(p) / 2; |
257 | } | 264 | } |
258 | 265 | ||
266 | static void mpc52xx_psc_get_irq(struct uart_port *port, struct device_node *np) | ||
267 | { | ||
268 | port->irqflags = IRQF_DISABLED; | ||
269 | port->irq = irq_of_parse_and_map(np, 0); | ||
270 | } | ||
271 | |||
272 | /* 52xx specific interrupt handler. The caller holds the port lock */ | ||
273 | static irqreturn_t mpc52xx_psc_handle_irq(struct uart_port *port) | ||
274 | { | ||
275 | return mpc5xxx_uart_process_int(port); | ||
276 | } | ||
277 | |||
259 | static struct psc_ops mpc52xx_psc_ops = { | 278 | static struct psc_ops mpc52xx_psc_ops = { |
260 | .fifo_init = mpc52xx_psc_fifo_init, | 279 | .fifo_init = mpc52xx_psc_fifo_init, |
261 | .raw_rx_rdy = mpc52xx_psc_raw_rx_rdy, | 280 | .raw_rx_rdy = mpc52xx_psc_raw_rx_rdy, |
@@ -273,14 +292,32 @@ static struct psc_ops mpc52xx_psc_ops = { | |||
273 | .cw_disable_ints = mpc52xx_psc_cw_disable_ints, | 292 | .cw_disable_ints = mpc52xx_psc_cw_disable_ints, |
274 | .cw_restore_ints = mpc52xx_psc_cw_restore_ints, | 293 | .cw_restore_ints = mpc52xx_psc_cw_restore_ints, |
275 | .getuartclk = mpc52xx_getuartclk, | 294 | .getuartclk = mpc52xx_getuartclk, |
295 | .get_irq = mpc52xx_psc_get_irq, | ||
296 | .handle_irq = mpc52xx_psc_handle_irq, | ||
276 | }; | 297 | }; |
277 | 298 | ||
278 | #endif /* CONFIG_MPC52xx */ | 299 | #endif /* CONFIG_MPC52xx */ |
279 | 300 | ||
280 | #ifdef CONFIG_PPC_MPC512x | 301 | #ifdef CONFIG_PPC_MPC512x |
281 | #define FIFO_512x(port) ((struct mpc512x_psc_fifo __iomem *)(PSC(port)+1)) | 302 | #define FIFO_512x(port) ((struct mpc512x_psc_fifo __iomem *)(PSC(port)+1)) |
303 | |||
304 | /* PSC FIFO Controller for mpc512x */ | ||
305 | struct psc_fifoc { | ||
306 | u32 fifoc_cmd; | ||
307 | u32 fifoc_int; | ||
308 | u32 fifoc_dma; | ||
309 | u32 fifoc_axe; | ||
310 | u32 fifoc_debug; | ||
311 | }; | ||
312 | |||
313 | static struct psc_fifoc __iomem *psc_fifoc; | ||
314 | static unsigned int psc_fifoc_irq; | ||
315 | |||
282 | static void mpc512x_psc_fifo_init(struct uart_port *port) | 316 | static void mpc512x_psc_fifo_init(struct uart_port *port) |
283 | { | 317 | { |
318 | /* /32 prescaler */ | ||
319 | out_be16(&PSC(port)->mpc52xx_psc_clock_select, 0xdd00); | ||
320 | |||
284 | out_be32(&FIFO_512x(port)->txcmd, MPC512x_PSC_FIFO_RESET_SLICE); | 321 | out_be32(&FIFO_512x(port)->txcmd, MPC512x_PSC_FIFO_RESET_SLICE); |
285 | out_be32(&FIFO_512x(port)->txcmd, MPC512x_PSC_FIFO_ENABLE_SLICE); | 322 | out_be32(&FIFO_512x(port)->txcmd, MPC512x_PSC_FIFO_ENABLE_SLICE); |
286 | out_be32(&FIFO_512x(port)->txalarm, 1); | 323 | out_be32(&FIFO_512x(port)->txalarm, 1); |
@@ -393,6 +430,160 @@ static unsigned long mpc512x_getuartclk(void *p) | |||
393 | return mpc5xxx_get_bus_frequency(p); | 430 | return mpc5xxx_get_bus_frequency(p); |
394 | } | 431 | } |
395 | 432 | ||
433 | #define DEFAULT_FIFO_SIZE 16 | ||
434 | |||
435 | static unsigned int __init get_fifo_size(struct device_node *np, | ||
436 | char *fifo_name) | ||
437 | { | ||
438 | const unsigned int *fp; | ||
439 | |||
440 | fp = of_get_property(np, fifo_name, NULL); | ||
441 | if (fp) | ||
442 | return *fp; | ||
443 | |||
444 | pr_warning("no %s property in %s node, defaulting to %d\n", | ||
445 | fifo_name, np->full_name, DEFAULT_FIFO_SIZE); | ||
446 | |||
447 | return DEFAULT_FIFO_SIZE; | ||
448 | } | ||
449 | |||
450 | #define FIFOC(_base) ((struct mpc512x_psc_fifo __iomem *) \ | ||
451 | ((u32)(_base) + sizeof(struct mpc52xx_psc))) | ||
452 | |||
453 | /* Init PSC FIFO Controller */ | ||
454 | static int __init mpc512x_psc_fifoc_init(void) | ||
455 | { | ||
456 | struct device_node *np; | ||
457 | void __iomem *psc; | ||
458 | unsigned int tx_fifo_size; | ||
459 | unsigned int rx_fifo_size; | ||
460 | int fifobase = 0; /* current fifo address in 32 bit words */ | ||
461 | |||
462 | np = of_find_compatible_node(NULL, NULL, | ||
463 | "fsl,mpc5121-psc-fifo"); | ||
464 | if (!np) { | ||
465 | pr_err("%s: Can't find FIFOC node\n", __func__); | ||
466 | return -ENODEV; | ||
467 | } | ||
468 | |||
469 | psc_fifoc = of_iomap(np, 0); | ||
470 | if (!psc_fifoc) { | ||
471 | pr_err("%s: Can't map FIFOC\n", __func__); | ||
472 | return -ENODEV; | ||
473 | } | ||
474 | |||
475 | psc_fifoc_irq = irq_of_parse_and_map(np, 0); | ||
476 | of_node_put(np); | ||
477 | if (psc_fifoc_irq == NO_IRQ) { | ||
478 | pr_err("%s: Can't get FIFOC irq\n", __func__); | ||
479 | iounmap(psc_fifoc); | ||
480 | return -ENODEV; | ||
481 | } | ||
482 | |||
483 | for_each_compatible_node(np, NULL, "fsl,mpc5121-psc-uart") { | ||
484 | tx_fifo_size = get_fifo_size(np, "fsl,tx-fifo-size"); | ||
485 | rx_fifo_size = get_fifo_size(np, "fsl,rx-fifo-size"); | ||
486 | |||
487 | /* size in register is in 4 byte units */ | ||
488 | tx_fifo_size /= 4; | ||
489 | rx_fifo_size /= 4; | ||
490 | if (!tx_fifo_size) | ||
491 | tx_fifo_size = 1; | ||
492 | if (!rx_fifo_size) | ||
493 | rx_fifo_size = 1; | ||
494 | |||
495 | psc = of_iomap(np, 0); | ||
496 | if (!psc) { | ||
497 | pr_err("%s: Can't map %s device\n", | ||
498 | __func__, np->full_name); | ||
499 | continue; | ||
500 | } | ||
501 | |||
502 | /* FIFO space is 4KiB, check if requested size is available */ | ||
503 | if ((fifobase + tx_fifo_size + rx_fifo_size) > 0x1000) { | ||
504 | pr_err("%s: no fifo space available for %s\n", | ||
505 | __func__, np->full_name); | ||
506 | iounmap(psc); | ||
507 | /* | ||
508 | * chances are that another device requests less | ||
509 | * fifo space, so we continue. | ||
510 | */ | ||
511 | continue; | ||
512 | } | ||
513 | /* set tx and rx fifo size registers */ | ||
514 | out_be32(&FIFOC(psc)->txsz, (fifobase << 16) | tx_fifo_size); | ||
515 | fifobase += tx_fifo_size; | ||
516 | out_be32(&FIFOC(psc)->rxsz, (fifobase << 16) | rx_fifo_size); | ||
517 | fifobase += rx_fifo_size; | ||
518 | |||
519 | /* reset and enable the slices */ | ||
520 | out_be32(&FIFOC(psc)->txcmd, 0x80); | ||
521 | out_be32(&FIFOC(psc)->txcmd, 0x01); | ||
522 | out_be32(&FIFOC(psc)->rxcmd, 0x80); | ||
523 | out_be32(&FIFOC(psc)->rxcmd, 0x01); | ||
524 | |||
525 | iounmap(psc); | ||
526 | } | ||
527 | |||
528 | return 0; | ||
529 | } | ||
530 | |||
531 | static void __exit mpc512x_psc_fifoc_uninit(void) | ||
532 | { | ||
533 | iounmap(psc_fifoc); | ||
534 | } | ||
535 | |||
536 | /* 512x specific interrupt handler. The caller holds the port lock */ | ||
537 | static irqreturn_t mpc512x_psc_handle_irq(struct uart_port *port) | ||
538 | { | ||
539 | unsigned long fifoc_int; | ||
540 | int psc_num; | ||
541 | |||
542 | /* Read pending PSC FIFOC interrupts */ | ||
543 | fifoc_int = in_be32(&psc_fifoc->fifoc_int); | ||
544 | |||
545 | /* Check if it is an interrupt for this port */ | ||
546 | psc_num = (port->mapbase & 0xf00) >> 8; | ||
547 | if (test_bit(psc_num, &fifoc_int) || | ||
548 | test_bit(psc_num + 16, &fifoc_int)) | ||
549 | return mpc5xxx_uart_process_int(port); | ||
550 | |||
551 | return IRQ_NONE; | ||
552 | } | ||
553 | |||
554 | static int mpc512x_psc_clock(struct uart_port *port, int enable) | ||
555 | { | ||
556 | struct clk *psc_clk; | ||
557 | int psc_num; | ||
558 | char clk_name[10]; | ||
559 | |||
560 | if (uart_console(port)) | ||
561 | return 0; | ||
562 | |||
563 | psc_num = (port->mapbase & 0xf00) >> 8; | ||
564 | snprintf(clk_name, sizeof(clk_name), "psc%d_clk", psc_num); | ||
565 | psc_clk = clk_get(port->dev, clk_name); | ||
566 | if (IS_ERR(psc_clk)) { | ||
567 | dev_err(port->dev, "Failed to get PSC clock entry!\n"); | ||
568 | return -ENODEV; | ||
569 | } | ||
570 | |||
571 | dev_dbg(port->dev, "%s %sable\n", clk_name, enable ? "en" : "dis"); | ||
572 | |||
573 | if (enable) | ||
574 | clk_enable(psc_clk); | ||
575 | else | ||
576 | clk_disable(psc_clk); | ||
577 | |||
578 | return 0; | ||
579 | } | ||
580 | |||
581 | static void mpc512x_psc_get_irq(struct uart_port *port, struct device_node *np) | ||
582 | { | ||
583 | port->irqflags = IRQF_SHARED; | ||
584 | port->irq = psc_fifoc_irq; | ||
585 | } | ||
586 | |||
396 | static struct psc_ops mpc512x_psc_ops = { | 587 | static struct psc_ops mpc512x_psc_ops = { |
397 | .fifo_init = mpc512x_psc_fifo_init, | 588 | .fifo_init = mpc512x_psc_fifo_init, |
398 | .raw_rx_rdy = mpc512x_psc_raw_rx_rdy, | 589 | .raw_rx_rdy = mpc512x_psc_raw_rx_rdy, |
@@ -410,6 +601,11 @@ static struct psc_ops mpc512x_psc_ops = { | |||
410 | .cw_disable_ints = mpc512x_psc_cw_disable_ints, | 601 | .cw_disable_ints = mpc512x_psc_cw_disable_ints, |
411 | .cw_restore_ints = mpc512x_psc_cw_restore_ints, | 602 | .cw_restore_ints = mpc512x_psc_cw_restore_ints, |
412 | .getuartclk = mpc512x_getuartclk, | 603 | .getuartclk = mpc512x_getuartclk, |
604 | .clock = mpc512x_psc_clock, | ||
605 | .fifoc_init = mpc512x_psc_fifoc_init, | ||
606 | .fifoc_uninit = mpc512x_psc_fifoc_uninit, | ||
607 | .get_irq = mpc512x_psc_get_irq, | ||
608 | .handle_irq = mpc512x_psc_handle_irq, | ||
413 | }; | 609 | }; |
414 | #endif | 610 | #endif |
415 | 611 | ||
@@ -519,10 +715,15 @@ mpc52xx_uart_startup(struct uart_port *port) | |||
519 | struct mpc52xx_psc __iomem *psc = PSC(port); | 715 | struct mpc52xx_psc __iomem *psc = PSC(port); |
520 | int ret; | 716 | int ret; |
521 | 717 | ||
718 | if (psc_ops->clock) { | ||
719 | ret = psc_ops->clock(port, 1); | ||
720 | if (ret) | ||
721 | return ret; | ||
722 | } | ||
723 | |||
522 | /* Request IRQ */ | 724 | /* Request IRQ */ |
523 | ret = request_irq(port->irq, mpc52xx_uart_int, | 725 | ret = request_irq(port->irq, mpc52xx_uart_int, |
524 | IRQF_DISABLED | IRQF_SAMPLE_RANDOM, | 726 | port->irqflags, "mpc52xx_psc_uart", port); |
525 | "mpc52xx_psc_uart", port); | ||
526 | if (ret) | 727 | if (ret) |
527 | return ret; | 728 | return ret; |
528 | 729 | ||
@@ -553,6 +754,9 @@ mpc52xx_uart_shutdown(struct uart_port *port) | |||
553 | port->read_status_mask = 0; | 754 | port->read_status_mask = 0; |
554 | out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask); | 755 | out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask); |
555 | 756 | ||
757 | if (psc_ops->clock) | ||
758 | psc_ops->clock(port, 0); | ||
759 | |||
556 | /* Release interrupt */ | 760 | /* Release interrupt */ |
557 | free_irq(port->irq, port); | 761 | free_irq(port->irq, port); |
558 | } | 762 | } |
@@ -851,15 +1055,12 @@ mpc52xx_uart_int_tx_chars(struct uart_port *port) | |||
851 | } | 1055 | } |
852 | 1056 | ||
853 | static irqreturn_t | 1057 | static irqreturn_t |
854 | mpc52xx_uart_int(int irq, void *dev_id) | 1058 | mpc5xxx_uart_process_int(struct uart_port *port) |
855 | { | 1059 | { |
856 | struct uart_port *port = dev_id; | ||
857 | unsigned long pass = ISR_PASS_LIMIT; | 1060 | unsigned long pass = ISR_PASS_LIMIT; |
858 | unsigned int keepgoing; | 1061 | unsigned int keepgoing; |
859 | u8 status; | 1062 | u8 status; |
860 | 1063 | ||
861 | spin_lock(&port->lock); | ||
862 | |||
863 | /* While we have stuff to do, we continue */ | 1064 | /* While we have stuff to do, we continue */ |
864 | do { | 1065 | do { |
865 | /* If we don't find anything to do, we stop */ | 1066 | /* If we don't find anything to do, we stop */ |
@@ -886,11 +1087,23 @@ mpc52xx_uart_int(int irq, void *dev_id) | |||
886 | 1087 | ||
887 | } while (keepgoing); | 1088 | } while (keepgoing); |
888 | 1089 | ||
889 | spin_unlock(&port->lock); | ||
890 | |||
891 | return IRQ_HANDLED; | 1090 | return IRQ_HANDLED; |
892 | } | 1091 | } |
893 | 1092 | ||
1093 | static irqreturn_t | ||
1094 | mpc52xx_uart_int(int irq, void *dev_id) | ||
1095 | { | ||
1096 | struct uart_port *port = dev_id; | ||
1097 | irqreturn_t ret; | ||
1098 | |||
1099 | spin_lock(&port->lock); | ||
1100 | |||
1101 | ret = psc_ops->handle_irq(port); | ||
1102 | |||
1103 | spin_unlock(&port->lock); | ||
1104 | |||
1105 | return ret; | ||
1106 | } | ||
894 | 1107 | ||
895 | /* ======================================================================== */ | 1108 | /* ======================================================================== */ |
896 | /* Console ( if applicable ) */ | 1109 | /* Console ( if applicable ) */ |
@@ -1152,7 +1365,7 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) | |||
1152 | return -EINVAL; | 1365 | return -EINVAL; |
1153 | } | 1366 | } |
1154 | 1367 | ||
1155 | port->irq = irq_of_parse_and_map(op->node, 0); | 1368 | psc_ops->get_irq(port, op->node); |
1156 | if (port->irq == NO_IRQ) { | 1369 | if (port->irq == NO_IRQ) { |
1157 | dev_dbg(&op->dev, "Could not get irq\n"); | 1370 | dev_dbg(&op->dev, "Could not get irq\n"); |
1158 | return -EINVAL; | 1371 | return -EINVAL; |
@@ -1163,10 +1376,8 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) | |||
1163 | 1376 | ||
1164 | /* Add the port to the uart sub-system */ | 1377 | /* Add the port to the uart sub-system */ |
1165 | ret = uart_add_one_port(&mpc52xx_uart_driver, port); | 1378 | ret = uart_add_one_port(&mpc52xx_uart_driver, port); |
1166 | if (ret) { | 1379 | if (ret) |
1167 | irq_dispose_mapping(port->irq); | ||
1168 | return ret; | 1380 | return ret; |
1169 | } | ||
1170 | 1381 | ||
1171 | dev_set_drvdata(&op->dev, (void *)port); | 1382 | dev_set_drvdata(&op->dev, (void *)port); |
1172 | return 0; | 1383 | return 0; |
@@ -1178,10 +1389,8 @@ mpc52xx_uart_of_remove(struct of_device *op) | |||
1178 | struct uart_port *port = dev_get_drvdata(&op->dev); | 1389 | struct uart_port *port = dev_get_drvdata(&op->dev); |
1179 | dev_set_drvdata(&op->dev, NULL); | 1390 | dev_set_drvdata(&op->dev, NULL); |
1180 | 1391 | ||
1181 | if (port) { | 1392 | if (port) |
1182 | uart_remove_one_port(&mpc52xx_uart_driver, port); | 1393 | uart_remove_one_port(&mpc52xx_uart_driver, port); |
1183 | irq_dispose_mapping(port->irq); | ||
1184 | } | ||
1185 | 1394 | ||
1186 | return 0; | 1395 | return 0; |
1187 | } | 1396 | } |
@@ -1288,6 +1497,15 @@ mpc52xx_uart_init(void) | |||
1288 | 1497 | ||
1289 | mpc52xx_uart_of_enumerate(); | 1498 | mpc52xx_uart_of_enumerate(); |
1290 | 1499 | ||
1500 | /* | ||
1501 | * Map the PSC FIFO Controller and init if on MPC512x. | ||
1502 | */ | ||
1503 | if (psc_ops->fifoc_init) { | ||
1504 | ret = psc_ops->fifoc_init(); | ||
1505 | if (ret) | ||
1506 | return ret; | ||
1507 | } | ||
1508 | |||
1291 | ret = of_register_platform_driver(&mpc52xx_uart_of_driver); | 1509 | ret = of_register_platform_driver(&mpc52xx_uart_of_driver); |
1292 | if (ret) { | 1510 | if (ret) { |
1293 | printk(KERN_ERR "%s: of_register_platform_driver failed (%i)\n", | 1511 | printk(KERN_ERR "%s: of_register_platform_driver failed (%i)\n", |
@@ -1302,6 +1520,9 @@ mpc52xx_uart_init(void) | |||
1302 | static void __exit | 1520 | static void __exit |
1303 | mpc52xx_uart_exit(void) | 1521 | mpc52xx_uart_exit(void) |
1304 | { | 1522 | { |
1523 | if (psc_ops->fifoc_uninit) | ||
1524 | psc_ops->fifoc_uninit(); | ||
1525 | |||
1305 | of_unregister_platform_driver(&mpc52xx_uart_of_driver); | 1526 | of_unregister_platform_driver(&mpc52xx_uart_of_driver); |
1306 | uart_unregister_driver(&mpc52xx_uart_driver); | 1527 | uart_unregister_driver(&mpc52xx_uart_driver); |
1307 | } | 1528 | } |
diff --git a/drivers/serial/msm_serial.c b/drivers/serial/msm_serial.c index b05c5aa02cb4..ecdc0facf7ee 100644 --- a/drivers/serial/msm_serial.c +++ b/drivers/serial/msm_serial.c | |||
@@ -691,6 +691,7 @@ static int __init msm_serial_probe(struct platform_device *pdev) | |||
691 | struct msm_port *msm_port; | 691 | struct msm_port *msm_port; |
692 | struct resource *resource; | 692 | struct resource *resource; |
693 | struct uart_port *port; | 693 | struct uart_port *port; |
694 | int irq; | ||
694 | 695 | ||
695 | if (unlikely(pdev->id < 0 || pdev->id >= UART_NR)) | 696 | if (unlikely(pdev->id < 0 || pdev->id >= UART_NR)) |
696 | return -ENXIO; | 697 | return -ENXIO; |
@@ -711,9 +712,10 @@ static int __init msm_serial_probe(struct platform_device *pdev) | |||
711 | return -ENXIO; | 712 | return -ENXIO; |
712 | port->mapbase = resource->start; | 713 | port->mapbase = resource->start; |
713 | 714 | ||
714 | port->irq = platform_get_irq(pdev, 0); | 715 | irq = platform_get_irq(pdev, 0); |
715 | if (unlikely(port->irq < 0)) | 716 | if (unlikely(irq < 0)) |
716 | return -ENXIO; | 717 | return -ENXIO; |
718 | port->irq = irq; | ||
717 | 719 | ||
718 | platform_set_drvdata(pdev, port); | 720 | platform_set_drvdata(pdev, port); |
719 | 721 | ||
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index 683e66f18e8c..f020de1cdd50 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c | |||
@@ -63,11 +63,17 @@ | |||
63 | #include <asm/sections.h> | 63 | #include <asm/sections.h> |
64 | #include <asm/io.h> | 64 | #include <asm/io.h> |
65 | #include <asm/irq.h> | 65 | #include <asm/irq.h> |
66 | |||
67 | #ifdef CONFIG_PPC_PMAC | ||
66 | #include <asm/prom.h> | 68 | #include <asm/prom.h> |
67 | #include <asm/machdep.h> | 69 | #include <asm/machdep.h> |
68 | #include <asm/pmac_feature.h> | 70 | #include <asm/pmac_feature.h> |
69 | #include <asm/dbdma.h> | 71 | #include <asm/dbdma.h> |
70 | #include <asm/macio.h> | 72 | #include <asm/macio.h> |
73 | #else | ||
74 | #include <linux/platform_device.h> | ||
75 | #define of_machine_is_compatible(x) (0) | ||
76 | #endif | ||
71 | 77 | ||
72 | #if defined (CONFIG_SERIAL_PMACZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | 78 | #if defined (CONFIG_SERIAL_PMACZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) |
73 | #define SUPPORT_SYSRQ | 79 | #define SUPPORT_SYSRQ |
@@ -83,11 +89,9 @@ | |||
83 | 89 | ||
84 | static char version[] __initdata = "pmac_zilog: 0.6 (Benjamin Herrenschmidt <benh@kernel.crashing.org>)"; | 90 | static char version[] __initdata = "pmac_zilog: 0.6 (Benjamin Herrenschmidt <benh@kernel.crashing.org>)"; |
85 | MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>"); | 91 | MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>"); |
86 | MODULE_DESCRIPTION("Driver for the PowerMac serial ports."); | 92 | MODULE_DESCRIPTION("Driver for the Mac and PowerMac serial ports."); |
87 | MODULE_LICENSE("GPL"); | 93 | MODULE_LICENSE("GPL"); |
88 | 94 | ||
89 | #define PWRDBG(fmt, arg...) printk(KERN_DEBUG fmt , ## arg) | ||
90 | |||
91 | #ifdef CONFIG_SERIAL_PMACZILOG_TTYS | 95 | #ifdef CONFIG_SERIAL_PMACZILOG_TTYS |
92 | #define PMACZILOG_MAJOR TTY_MAJOR | 96 | #define PMACZILOG_MAJOR TTY_MAJOR |
93 | #define PMACZILOG_MINOR 64 | 97 | #define PMACZILOG_MINOR 64 |
@@ -153,8 +157,8 @@ static void pmz_load_zsregs(struct uart_pmac_port *uap, u8 *regs) | |||
153 | write_zsreg(uap, R10, regs[R10]); | 157 | write_zsreg(uap, R10, regs[R10]); |
154 | 158 | ||
155 | /* Set TX/RX controls sans the enable bits. */ | 159 | /* Set TX/RX controls sans the enable bits. */ |
156 | write_zsreg(uap, R3, regs[R3] & ~RxENABLE); | 160 | write_zsreg(uap, R3, regs[R3] & ~RxENABLE); |
157 | write_zsreg(uap, R5, regs[R5] & ~TxENABLE); | 161 | write_zsreg(uap, R5, regs[R5] & ~TxENABLE); |
158 | 162 | ||
159 | /* now set R7 "prime" on ESCC */ | 163 | /* now set R7 "prime" on ESCC */ |
160 | write_zsreg(uap, R15, regs[R15] | EN85C30); | 164 | write_zsreg(uap, R15, regs[R15] | EN85C30); |
@@ -205,7 +209,7 @@ static void pmz_load_zsregs(struct uart_pmac_port *uap, u8 *regs) | |||
205 | */ | 209 | */ |
206 | static void pmz_maybe_update_regs(struct uart_pmac_port *uap) | 210 | static void pmz_maybe_update_regs(struct uart_pmac_port *uap) |
207 | { | 211 | { |
208 | if (!ZS_REGS_HELD(uap)) { | 212 | if (!ZS_REGS_HELD(uap)) { |
209 | if (ZS_TX_ACTIVE(uap)) { | 213 | if (ZS_TX_ACTIVE(uap)) { |
210 | uap->flags |= PMACZILOG_FLAG_REGS_HELD; | 214 | uap->flags |= PMACZILOG_FLAG_REGS_HELD; |
211 | } else { | 215 | } else { |
@@ -281,7 +285,7 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap) | |||
281 | spin_lock(&uap->port.lock); | 285 | spin_lock(&uap->port.lock); |
282 | if (swallow) | 286 | if (swallow) |
283 | goto next_char; | 287 | goto next_char; |
284 | } | 288 | } |
285 | #endif /* CONFIG_MAGIC_SYSRQ && CONFIG_SERIAL_CORE_CONSOLE */ | 289 | #endif /* CONFIG_MAGIC_SYSRQ && CONFIG_SERIAL_CORE_CONSOLE */ |
286 | 290 | ||
287 | /* A real serial line, record the character and status. */ | 291 | /* A real serial line, record the character and status. */ |
@@ -317,7 +321,7 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap) | |||
317 | 321 | ||
318 | if (uap->port.ignore_status_mask == 0xff || | 322 | if (uap->port.ignore_status_mask == 0xff || |
319 | (r1 & uap->port.ignore_status_mask) == 0) { | 323 | (r1 & uap->port.ignore_status_mask) == 0) { |
320 | tty_insert_flip_char(tty, ch, flag); | 324 | tty_insert_flip_char(tty, ch, flag); |
321 | } | 325 | } |
322 | if (r1 & Rx_OVR) | 326 | if (r1 & Rx_OVR) |
323 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 327 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
@@ -341,7 +345,7 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap) | |||
341 | uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK); | 345 | uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK); |
342 | write_zsreg(uap, R1, uap->curregs[R1]); | 346 | write_zsreg(uap, R1, uap->curregs[R1]); |
343 | zssync(uap); | 347 | zssync(uap); |
344 | dev_err(&uap->dev->ofdev.dev, "pmz: rx irq flood !\n"); | 348 | pmz_error("pmz: rx irq flood !\n"); |
345 | return tty; | 349 | return tty; |
346 | } | 350 | } |
347 | 351 | ||
@@ -470,47 +474,47 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) | |||
470 | 474 | ||
471 | uap_a = pmz_get_port_A(uap); | 475 | uap_a = pmz_get_port_A(uap); |
472 | uap_b = uap_a->mate; | 476 | uap_b = uap_a->mate; |
473 | 477 | ||
474 | spin_lock(&uap_a->port.lock); | 478 | spin_lock(&uap_a->port.lock); |
475 | r3 = read_zsreg(uap_a, R3); | 479 | r3 = read_zsreg(uap_a, R3); |
476 | 480 | ||
477 | #ifdef DEBUG_HARD | 481 | #ifdef DEBUG_HARD |
478 | pmz_debug("irq, r3: %x\n", r3); | 482 | pmz_debug("irq, r3: %x\n", r3); |
479 | #endif | 483 | #endif |
480 | /* Channel A */ | 484 | /* Channel A */ |
481 | tty = NULL; | 485 | tty = NULL; |
482 | if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { | 486 | if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { |
483 | write_zsreg(uap_a, R0, RES_H_IUS); | 487 | write_zsreg(uap_a, R0, RES_H_IUS); |
484 | zssync(uap_a); | 488 | zssync(uap_a); |
485 | if (r3 & CHAEXT) | 489 | if (r3 & CHAEXT) |
486 | pmz_status_handle(uap_a); | 490 | pmz_status_handle(uap_a); |
487 | if (r3 & CHARxIP) | 491 | if (r3 & CHARxIP) |
488 | tty = pmz_receive_chars(uap_a); | 492 | tty = pmz_receive_chars(uap_a); |
489 | if (r3 & CHATxIP) | 493 | if (r3 & CHATxIP) |
490 | pmz_transmit_chars(uap_a); | 494 | pmz_transmit_chars(uap_a); |
491 | rc = IRQ_HANDLED; | 495 | rc = IRQ_HANDLED; |
492 | } | 496 | } |
493 | spin_unlock(&uap_a->port.lock); | 497 | spin_unlock(&uap_a->port.lock); |
494 | if (tty != NULL) | 498 | if (tty != NULL) |
495 | tty_flip_buffer_push(tty); | 499 | tty_flip_buffer_push(tty); |
496 | 500 | ||
497 | if (uap_b->node == NULL) | 501 | if (uap_b->node == NULL) |
498 | goto out; | 502 | goto out; |
499 | 503 | ||
500 | spin_lock(&uap_b->port.lock); | 504 | spin_lock(&uap_b->port.lock); |
501 | tty = NULL; | 505 | tty = NULL; |
502 | if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { | 506 | if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { |
503 | write_zsreg(uap_b, R0, RES_H_IUS); | 507 | write_zsreg(uap_b, R0, RES_H_IUS); |
504 | zssync(uap_b); | 508 | zssync(uap_b); |
505 | if (r3 & CHBEXT) | 509 | if (r3 & CHBEXT) |
506 | pmz_status_handle(uap_b); | 510 | pmz_status_handle(uap_b); |
507 | if (r3 & CHBRxIP) | 511 | if (r3 & CHBRxIP) |
508 | tty = pmz_receive_chars(uap_b); | 512 | tty = pmz_receive_chars(uap_b); |
509 | if (r3 & CHBTxIP) | 513 | if (r3 & CHBTxIP) |
510 | pmz_transmit_chars(uap_b); | 514 | pmz_transmit_chars(uap_b); |
511 | rc = IRQ_HANDLED; | 515 | rc = IRQ_HANDLED; |
512 | } | 516 | } |
513 | spin_unlock(&uap_b->port.lock); | 517 | spin_unlock(&uap_b->port.lock); |
514 | if (tty != NULL) | 518 | if (tty != NULL) |
515 | tty_flip_buffer_push(tty); | 519 | tty_flip_buffer_push(tty); |
516 | 520 | ||
@@ -718,7 +722,7 @@ static void pmz_enable_ms(struct uart_port *port) | |||
718 | 722 | ||
719 | if (ZS_IS_ASLEEP(uap)) | 723 | if (ZS_IS_ASLEEP(uap)) |
720 | return; | 724 | return; |
721 | /* NOTE: Not subject to 'transmitter active' rule. */ | 725 | /* NOTE: Not subject to 'transmitter active' rule. */ |
722 | write_zsreg(uap, R15, uap->curregs[R15]); | 726 | write_zsreg(uap, R15, uap->curregs[R15]); |
723 | } | 727 | } |
724 | } | 728 | } |
@@ -748,7 +752,7 @@ static void pmz_break_ctl(struct uart_port *port, int break_state) | |||
748 | if (new_reg != uap->curregs[R5]) { | 752 | if (new_reg != uap->curregs[R5]) { |
749 | uap->curregs[R5] = new_reg; | 753 | uap->curregs[R5] = new_reg; |
750 | 754 | ||
751 | /* NOTE: Not subject to 'transmitter active' rule. */ | 755 | /* NOTE: Not subject to 'transmitter active' rule. */ |
752 | if (ZS_IS_ASLEEP(uap)) | 756 | if (ZS_IS_ASLEEP(uap)) |
753 | return; | 757 | return; |
754 | write_zsreg(uap, R5, uap->curregs[R5]); | 758 | write_zsreg(uap, R5, uap->curregs[R5]); |
@@ -757,6 +761,8 @@ static void pmz_break_ctl(struct uart_port *port, int break_state) | |||
757 | spin_unlock_irqrestore(&port->lock, flags); | 761 | spin_unlock_irqrestore(&port->lock, flags); |
758 | } | 762 | } |
759 | 763 | ||
764 | #ifdef CONFIG_PPC_PMAC | ||
765 | |||
760 | /* | 766 | /* |
761 | * Turn power on or off to the SCC and associated stuff | 767 | * Turn power on or off to the SCC and associated stuff |
762 | * (port drivers, modem, IR port, etc.) | 768 | * (port drivers, modem, IR port, etc.) |
@@ -792,6 +798,15 @@ static int pmz_set_scc_power(struct uart_pmac_port *uap, int state) | |||
792 | return delay; | 798 | return delay; |
793 | } | 799 | } |
794 | 800 | ||
801 | #else | ||
802 | |||
803 | static int pmz_set_scc_power(struct uart_pmac_port *uap, int state) | ||
804 | { | ||
805 | return 0; | ||
806 | } | ||
807 | |||
808 | #endif /* !CONFIG_PPC_PMAC */ | ||
809 | |||
795 | /* | 810 | /* |
796 | * FixZeroBug....Works around a bug in the SCC receving channel. | 811 | * FixZeroBug....Works around a bug in the SCC receving channel. |
797 | * Inspired from Darwin code, 15 Sept. 2000 -DanM | 812 | * Inspired from Darwin code, 15 Sept. 2000 -DanM |
@@ -908,7 +923,6 @@ static int __pmz_startup(struct uart_pmac_port *uap) | |||
908 | /* Remember status for DCD/CTS changes */ | 923 | /* Remember status for DCD/CTS changes */ |
909 | uap->prev_status = read_zsreg(uap, R0); | 924 | uap->prev_status = read_zsreg(uap, R0); |
910 | 925 | ||
911 | |||
912 | return pwr_delay; | 926 | return pwr_delay; |
913 | } | 927 | } |
914 | 928 | ||
@@ -955,9 +969,9 @@ static int pmz_startup(struct uart_port *port) | |||
955 | } | 969 | } |
956 | 970 | ||
957 | pmz_get_port_A(uap)->flags |= PMACZILOG_FLAG_IS_IRQ_ON; | 971 | pmz_get_port_A(uap)->flags |= PMACZILOG_FLAG_IS_IRQ_ON; |
958 | if (request_irq(uap->port.irq, pmz_interrupt, IRQF_SHARED, "PowerMac Zilog", uap)) { | 972 | if (request_irq(uap->port.irq, pmz_interrupt, IRQF_SHARED, |
959 | dev_err(&uap->dev->ofdev.dev, | 973 | "SCC", uap)) { |
960 | "Unable to register zs interrupt handler.\n"); | 974 | pmz_error("Unable to register zs interrupt handler.\n"); |
961 | pmz_set_scc_power(uap, 0); | 975 | pmz_set_scc_power(uap, 0); |
962 | mutex_unlock(&pmz_irq_mutex); | 976 | mutex_unlock(&pmz_irq_mutex); |
963 | return -ENXIO; | 977 | return -ENXIO; |
@@ -983,7 +997,7 @@ static int pmz_startup(struct uart_port *port) | |||
983 | if (!ZS_IS_EXTCLK(uap)) | 997 | if (!ZS_IS_EXTCLK(uap)) |
984 | uap->curregs[R1] |= EXT_INT_ENAB; | 998 | uap->curregs[R1] |= EXT_INT_ENAB; |
985 | write_zsreg(uap, R1, uap->curregs[R1]); | 999 | write_zsreg(uap, R1, uap->curregs[R1]); |
986 | spin_unlock_irqrestore(&port->lock, flags); | 1000 | spin_unlock_irqrestore(&port->lock, flags); |
987 | 1001 | ||
988 | pmz_debug("pmz: startup() done.\n"); | 1002 | pmz_debug("pmz: startup() done.\n"); |
989 | 1003 | ||
@@ -1003,7 +1017,7 @@ static void pmz_shutdown(struct uart_port *port) | |||
1003 | mutex_lock(&pmz_irq_mutex); | 1017 | mutex_lock(&pmz_irq_mutex); |
1004 | 1018 | ||
1005 | /* Release interrupt handler */ | 1019 | /* Release interrupt handler */ |
1006 | free_irq(uap->port.irq, uap); | 1020 | free_irq(uap->port.irq, uap); |
1007 | 1021 | ||
1008 | spin_lock_irqsave(&port->lock, flags); | 1022 | spin_lock_irqsave(&port->lock, flags); |
1009 | 1023 | ||
@@ -1051,7 +1065,6 @@ static void pmz_convert_to_zs(struct uart_pmac_port *uap, unsigned int cflag, | |||
1051 | { | 1065 | { |
1052 | int brg; | 1066 | int brg; |
1053 | 1067 | ||
1054 | |||
1055 | /* Switch to external clocking for IrDA high clock rates. That | 1068 | /* Switch to external clocking for IrDA high clock rates. That |
1056 | * code could be re-used for Midi interfaces with different | 1069 | * code could be re-used for Midi interfaces with different |
1057 | * multipliers | 1070 | * multipliers |
@@ -1198,7 +1211,7 @@ static void pmz_irda_setup(struct uart_pmac_port *uap, unsigned long *baud) | |||
1198 | while ((read_zsreg(uap, R0) & Tx_BUF_EMP) == 0 | 1211 | while ((read_zsreg(uap, R0) & Tx_BUF_EMP) == 0 |
1199 | || (read_zsreg(uap, R1) & ALL_SNT) == 0) { | 1212 | || (read_zsreg(uap, R1) & ALL_SNT) == 0) { |
1200 | if (--t <= 0) { | 1213 | if (--t <= 0) { |
1201 | dev_err(&uap->dev->ofdev.dev, "transmitter didn't drain\n"); | 1214 | pmz_error("transmitter didn't drain\n"); |
1202 | return; | 1215 | return; |
1203 | } | 1216 | } |
1204 | udelay(10); | 1217 | udelay(10); |
@@ -1214,7 +1227,7 @@ static void pmz_irda_setup(struct uart_pmac_port *uap, unsigned long *baud) | |||
1214 | read_zsdata(uap); | 1227 | read_zsdata(uap); |
1215 | mdelay(10); | 1228 | mdelay(10); |
1216 | if (--t <= 0) { | 1229 | if (--t <= 0) { |
1217 | dev_err(&uap->dev->ofdev.dev, "receiver didn't drain\n"); | 1230 | pmz_error("receiver didn't drain\n"); |
1218 | return; | 1231 | return; |
1219 | } | 1232 | } |
1220 | } | 1233 | } |
@@ -1223,20 +1236,19 @@ static void pmz_irda_setup(struct uart_pmac_port *uap, unsigned long *baud) | |||
1223 | uap->curregs[R5] |= DTR; | 1236 | uap->curregs[R5] |= DTR; |
1224 | write_zsreg(uap, R5, uap->curregs[R5]); | 1237 | write_zsreg(uap, R5, uap->curregs[R5]); |
1225 | zssync(uap); | 1238 | zssync(uap); |
1226 | mdelay(1); | 1239 | mdelay(1); |
1227 | 1240 | ||
1228 | /* Switch SCC to 19200 */ | 1241 | /* Switch SCC to 19200 */ |
1229 | pmz_convert_to_zs(uap, CS8, 0, 19200); | 1242 | pmz_convert_to_zs(uap, CS8, 0, 19200); |
1230 | pmz_load_zsregs(uap, uap->curregs); | 1243 | pmz_load_zsregs(uap, uap->curregs); |
1231 | mdelay(1); | 1244 | mdelay(1); |
1232 | 1245 | ||
1233 | /* Write get_version command byte */ | 1246 | /* Write get_version command byte */ |
1234 | write_zsdata(uap, 1); | 1247 | write_zsdata(uap, 1); |
1235 | t = 5000; | 1248 | t = 5000; |
1236 | while ((read_zsreg(uap, R0) & Rx_CH_AV) == 0) { | 1249 | while ((read_zsreg(uap, R0) & Rx_CH_AV) == 0) { |
1237 | if (--t <= 0) { | 1250 | if (--t <= 0) { |
1238 | dev_err(&uap->dev->ofdev.dev, | 1251 | pmz_error("irda_setup timed out on get_version byte\n"); |
1239 | "irda_setup timed out on get_version byte\n"); | ||
1240 | goto out; | 1252 | goto out; |
1241 | } | 1253 | } |
1242 | udelay(10); | 1254 | udelay(10); |
@@ -1244,8 +1256,7 @@ static void pmz_irda_setup(struct uart_pmac_port *uap, unsigned long *baud) | |||
1244 | version = read_zsdata(uap); | 1256 | version = read_zsdata(uap); |
1245 | 1257 | ||
1246 | if (version < 4) { | 1258 | if (version < 4) { |
1247 | dev_info(&uap->dev->ofdev.dev, "IrDA: dongle version %d not supported\n", | 1259 | pmz_info("IrDA: dongle version %d not supported\n", version); |
1248 | version); | ||
1249 | goto out; | 1260 | goto out; |
1250 | } | 1261 | } |
1251 | 1262 | ||
@@ -1254,18 +1265,16 @@ static void pmz_irda_setup(struct uart_pmac_port *uap, unsigned long *baud) | |||
1254 | t = 5000; | 1265 | t = 5000; |
1255 | while ((read_zsreg(uap, R0) & Rx_CH_AV) == 0) { | 1266 | while ((read_zsreg(uap, R0) & Rx_CH_AV) == 0) { |
1256 | if (--t <= 0) { | 1267 | if (--t <= 0) { |
1257 | dev_err(&uap->dev->ofdev.dev, | 1268 | pmz_error("irda_setup timed out on speed mode byte\n"); |
1258 | "irda_setup timed out on speed mode byte\n"); | ||
1259 | goto out; | 1269 | goto out; |
1260 | } | 1270 | } |
1261 | udelay(10); | 1271 | udelay(10); |
1262 | } | 1272 | } |
1263 | t = read_zsdata(uap); | 1273 | t = read_zsdata(uap); |
1264 | if (t != cmdbyte) | 1274 | if (t != cmdbyte) |
1265 | dev_err(&uap->dev->ofdev.dev, | 1275 | pmz_error("irda_setup speed mode byte = %x (%x)\n", t, cmdbyte); |
1266 | "irda_setup speed mode byte = %x (%x)\n", t, cmdbyte); | ||
1267 | 1276 | ||
1268 | dev_info(&uap->dev->ofdev.dev, "IrDA setup for %ld bps, dongle version: %d\n", | 1277 | pmz_info("IrDA setup for %ld bps, dongle version: %d\n", |
1269 | *baud, version); | 1278 | *baud, version); |
1270 | 1279 | ||
1271 | (void)read_zsdata(uap); | 1280 | (void)read_zsdata(uap); |
@@ -1415,7 +1424,7 @@ static void pmz_poll_put_char(struct uart_port *port, unsigned char c) | |||
1415 | write_zsdata(uap, c); | 1424 | write_zsdata(uap, c); |
1416 | } | 1425 | } |
1417 | 1426 | ||
1418 | #endif | 1427 | #endif /* CONFIG_CONSOLE_POLL */ |
1419 | 1428 | ||
1420 | static struct uart_ops pmz_pops = { | 1429 | static struct uart_ops pmz_pops = { |
1421 | .tx_empty = pmz_tx_empty, | 1430 | .tx_empty = pmz_tx_empty, |
@@ -1440,6 +1449,8 @@ static struct uart_ops pmz_pops = { | |||
1440 | #endif | 1449 | #endif |
1441 | }; | 1450 | }; |
1442 | 1451 | ||
1452 | #ifdef CONFIG_PPC_PMAC | ||
1453 | |||
1443 | /* | 1454 | /* |
1444 | * Setup one port structure after probing, HW is down at this point, | 1455 | * Setup one port structure after probing, HW is down at this point, |
1445 | * Unlike sunzilog, we don't need to pre-init the spinlock as we don't | 1456 | * Unlike sunzilog, we don't need to pre-init the spinlock as we don't |
@@ -1463,7 +1474,7 @@ static int __init pmz_init_port(struct uart_pmac_port *uap) | |||
1463 | return -ENODEV; | 1474 | return -ENODEV; |
1464 | uap->port.mapbase = r_ports.start; | 1475 | uap->port.mapbase = r_ports.start; |
1465 | uap->port.membase = ioremap(uap->port.mapbase, 0x1000); | 1476 | uap->port.membase = ioremap(uap->port.mapbase, 0x1000); |
1466 | 1477 | ||
1467 | uap->control_reg = uap->port.membase; | 1478 | uap->control_reg = uap->port.membase; |
1468 | uap->data_reg = uap->control_reg + 0x10; | 1479 | uap->data_reg = uap->control_reg + 0x10; |
1469 | 1480 | ||
@@ -1590,7 +1601,7 @@ static void pmz_dispose_port(struct uart_pmac_port *uap) | |||
1590 | } | 1601 | } |
1591 | 1602 | ||
1592 | /* | 1603 | /* |
1593 | * Called upon match with an escc node in the devive-tree. | 1604 | * Called upon match with an escc node in the device-tree. |
1594 | */ | 1605 | */ |
1595 | static int pmz_attach(struct macio_dev *mdev, const struct of_device_id *match) | 1606 | static int pmz_attach(struct macio_dev *mdev, const struct of_device_id *match) |
1596 | { | 1607 | { |
@@ -1812,7 +1823,7 @@ static int __init pmz_probe(void) | |||
1812 | pmz_ports[count].node = node_a; | 1823 | pmz_ports[count].node = node_a; |
1813 | pmz_ports[count+1].node = node_b; | 1824 | pmz_ports[count+1].node = node_b; |
1814 | pmz_ports[count].port.line = count; | 1825 | pmz_ports[count].port.line = count; |
1815 | pmz_ports[count+1].port.line = count+1; | 1826 | pmz_ports[count+1].port.line = count+1; |
1816 | 1827 | ||
1817 | /* | 1828 | /* |
1818 | * Setup the ports for real | 1829 | * Setup the ports for real |
@@ -1836,6 +1847,88 @@ next: | |||
1836 | return 0; | 1847 | return 0; |
1837 | } | 1848 | } |
1838 | 1849 | ||
1850 | #else | ||
1851 | |||
1852 | extern struct platform_device scc_a_pdev, scc_b_pdev; | ||
1853 | |||
1854 | static int __init pmz_init_port(struct uart_pmac_port *uap) | ||
1855 | { | ||
1856 | struct resource *r_ports; | ||
1857 | int irq; | ||
1858 | |||
1859 | r_ports = platform_get_resource(uap->node, IORESOURCE_MEM, 0); | ||
1860 | irq = platform_get_irq(uap->node, 0); | ||
1861 | if (!r_ports || !irq) | ||
1862 | return -ENODEV; | ||
1863 | |||
1864 | uap->port.mapbase = r_ports->start; | ||
1865 | uap->port.membase = (unsigned char __iomem *) r_ports->start; | ||
1866 | uap->port.iotype = UPIO_MEM; | ||
1867 | uap->port.irq = irq; | ||
1868 | uap->port.uartclk = ZS_CLOCK; | ||
1869 | uap->port.fifosize = 1; | ||
1870 | uap->port.ops = &pmz_pops; | ||
1871 | uap->port.type = PORT_PMAC_ZILOG; | ||
1872 | uap->port.flags = 0; | ||
1873 | |||
1874 | uap->control_reg = uap->port.membase; | ||
1875 | uap->data_reg = uap->control_reg + 4; | ||
1876 | uap->port_type = 0; | ||
1877 | |||
1878 | pmz_convert_to_zs(uap, CS8, 0, 9600); | ||
1879 | |||
1880 | return 0; | ||
1881 | } | ||
1882 | |||
1883 | static int __init pmz_probe(void) | ||
1884 | { | ||
1885 | int err; | ||
1886 | |||
1887 | pmz_ports_count = 0; | ||
1888 | |||
1889 | pmz_ports[0].mate = &pmz_ports[1]; | ||
1890 | pmz_ports[0].port.line = 0; | ||
1891 | pmz_ports[0].flags = PMACZILOG_FLAG_IS_CHANNEL_A; | ||
1892 | pmz_ports[0].node = &scc_a_pdev; | ||
1893 | err = pmz_init_port(&pmz_ports[0]); | ||
1894 | if (err) | ||
1895 | return err; | ||
1896 | pmz_ports_count++; | ||
1897 | |||
1898 | pmz_ports[1].mate = &pmz_ports[0]; | ||
1899 | pmz_ports[1].port.line = 1; | ||
1900 | pmz_ports[1].flags = 0; | ||
1901 | pmz_ports[1].node = &scc_b_pdev; | ||
1902 | err = pmz_init_port(&pmz_ports[1]); | ||
1903 | if (err) | ||
1904 | return err; | ||
1905 | pmz_ports_count++; | ||
1906 | |||
1907 | return 0; | ||
1908 | } | ||
1909 | |||
1910 | static void pmz_dispose_port(struct uart_pmac_port *uap) | ||
1911 | { | ||
1912 | memset(uap, 0, sizeof(struct uart_pmac_port)); | ||
1913 | } | ||
1914 | |||
1915 | static int __init pmz_attach(struct platform_device *pdev) | ||
1916 | { | ||
1917 | int i; | ||
1918 | |||
1919 | for (i = 0; i < pmz_ports_count; i++) | ||
1920 | if (pmz_ports[i].node == pdev) | ||
1921 | return 0; | ||
1922 | return -ENODEV; | ||
1923 | } | ||
1924 | |||
1925 | static int __exit pmz_detach(struct platform_device *pdev) | ||
1926 | { | ||
1927 | return 0; | ||
1928 | } | ||
1929 | |||
1930 | #endif /* !CONFIG_PPC_PMAC */ | ||
1931 | |||
1839 | #ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE | 1932 | #ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE |
1840 | 1933 | ||
1841 | static void pmz_console_write(struct console *con, const char *s, unsigned int count); | 1934 | static void pmz_console_write(struct console *con, const char *s, unsigned int count); |
@@ -1896,28 +1989,41 @@ err_out: | |||
1896 | return rc; | 1989 | return rc; |
1897 | } | 1990 | } |
1898 | 1991 | ||
1992 | #ifdef CONFIG_PPC_PMAC | ||
1993 | |||
1899 | static struct of_device_id pmz_match[] = | 1994 | static struct of_device_id pmz_match[] = |
1900 | { | 1995 | { |
1901 | { | 1996 | { |
1902 | .name = "ch-a", | 1997 | .name = "ch-a", |
1903 | }, | 1998 | }, |
1904 | { | 1999 | { |
1905 | .name = "ch-b", | 2000 | .name = "ch-b", |
1906 | }, | 2001 | }, |
1907 | {}, | 2002 | {}, |
1908 | }; | 2003 | }; |
1909 | MODULE_DEVICE_TABLE (of, pmz_match); | 2004 | MODULE_DEVICE_TABLE (of, pmz_match); |
1910 | 2005 | ||
1911 | static struct macio_driver pmz_driver = | 2006 | static struct macio_driver pmz_driver = { |
1912 | { | ||
1913 | .name = "pmac_zilog", | 2007 | .name = "pmac_zilog", |
1914 | .match_table = pmz_match, | 2008 | .match_table = pmz_match, |
1915 | .probe = pmz_attach, | 2009 | .probe = pmz_attach, |
1916 | .remove = pmz_detach, | 2010 | .remove = pmz_detach, |
1917 | .suspend = pmz_suspend, | 2011 | .suspend = pmz_suspend, |
1918 | .resume = pmz_resume, | 2012 | .resume = pmz_resume, |
1919 | }; | 2013 | }; |
1920 | 2014 | ||
2015 | #else | ||
2016 | |||
2017 | static struct platform_driver pmz_driver = { | ||
2018 | .remove = __exit_p(pmz_detach), | ||
2019 | .driver = { | ||
2020 | .name = "scc", | ||
2021 | .owner = THIS_MODULE, | ||
2022 | }, | ||
2023 | }; | ||
2024 | |||
2025 | #endif /* !CONFIG_PPC_PMAC */ | ||
2026 | |||
1921 | static int __init init_pmz(void) | 2027 | static int __init init_pmz(void) |
1922 | { | 2028 | { |
1923 | int rc, i; | 2029 | int rc, i; |
@@ -1952,19 +2058,27 @@ static int __init init_pmz(void) | |||
1952 | pmz_dispose_port(&pmz_ports[i]); | 2058 | pmz_dispose_port(&pmz_ports[i]); |
1953 | return rc; | 2059 | return rc; |
1954 | } | 2060 | } |
1955 | 2061 | ||
1956 | /* | 2062 | /* |
1957 | * Then we register the macio driver itself | 2063 | * Then we register the macio driver itself |
1958 | */ | 2064 | */ |
2065 | #ifdef CONFIG_PPC_PMAC | ||
1959 | return macio_register_driver(&pmz_driver); | 2066 | return macio_register_driver(&pmz_driver); |
2067 | #else | ||
2068 | return platform_driver_probe(&pmz_driver, pmz_attach); | ||
2069 | #endif | ||
1960 | } | 2070 | } |
1961 | 2071 | ||
1962 | static void __exit exit_pmz(void) | 2072 | static void __exit exit_pmz(void) |
1963 | { | 2073 | { |
1964 | int i; | 2074 | int i; |
1965 | 2075 | ||
2076 | #ifdef CONFIG_PPC_PMAC | ||
1966 | /* Get rid of macio-driver (detach from macio) */ | 2077 | /* Get rid of macio-driver (detach from macio) */ |
1967 | macio_unregister_driver(&pmz_driver); | 2078 | macio_unregister_driver(&pmz_driver); |
2079 | #else | ||
2080 | platform_driver_unregister(&pmz_driver); | ||
2081 | #endif | ||
1968 | 2082 | ||
1969 | for (i = 0; i < pmz_ports_count; i++) { | 2083 | for (i = 0; i < pmz_ports_count; i++) { |
1970 | struct uart_pmac_port *uport = &pmz_ports[i]; | 2084 | struct uart_pmac_port *uport = &pmz_ports[i]; |
@@ -2031,10 +2145,10 @@ static int __init pmz_console_setup(struct console *co, char *options) | |||
2031 | /* | 2145 | /* |
2032 | * XServe's default to 57600 bps | 2146 | * XServe's default to 57600 bps |
2033 | */ | 2147 | */ |
2034 | if (machine_is_compatible("RackMac1,1") | 2148 | if (of_machine_is_compatible("RackMac1,1") |
2035 | || machine_is_compatible("RackMac1,2") | 2149 | || of_machine_is_compatible("RackMac1,2") |
2036 | || machine_is_compatible("MacRISC4")) | 2150 | || of_machine_is_compatible("MacRISC4")) |
2037 | baud = 57600; | 2151 | baud = 57600; |
2038 | 2152 | ||
2039 | /* | 2153 | /* |
2040 | * Check whether an invalid uart number has been specified, and | 2154 | * 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 f6e77f12acd5..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 | }; |
@@ -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/serial_cs.c b/drivers/serial/serial_cs.c index 95421fa3b304..e91db4b38012 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c | |||
@@ -696,11 +696,11 @@ static int serial_config(struct pcmcia_device * link) | |||
696 | info->multi = info->quirk->multi; | 696 | info->multi = info->quirk->multi; |
697 | 697 | ||
698 | if (info->multi > 1) | 698 | if (info->multi > 1) |
699 | multi_config(link); | 699 | i = multi_config(link); |
700 | else | 700 | else |
701 | simple_config(link); | 701 | i = simple_config(link); |
702 | 702 | ||
703 | if (info->ndev == 0) | 703 | if (i || info->ndev == 0) |
704 | goto failed; | 704 | goto failed; |
705 | 705 | ||
706 | /* | 706 | /* |
@@ -715,6 +715,7 @@ static int serial_config(struct pcmcia_device * link) | |||
715 | return 0; | 715 | return 0; |
716 | 716 | ||
717 | failed: | 717 | failed: |
718 | dev_warn(&link->dev, "serial_cs: failed to initialize\n"); | ||
718 | serial_remove(link); | 719 | serial_remove(link); |
719 | return -ENODEV; | 720 | return -ENODEV; |
720 | } | 721 | } |
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 42f3333c4ad0..980f39449ee5 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -48,6 +48,9 @@ | |||
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/timer.h> | ||
51 | 54 | ||
52 | #ifdef CONFIG_SUPERH | 55 | #ifdef CONFIG_SUPERH |
53 | #include <asm/sh_bios.h> | 56 | #include <asm/sh_bios.h> |
@@ -84,6 +87,27 @@ struct sci_port { | |||
84 | struct clk *dclk; | 87 | struct clk *dclk; |
85 | 88 | ||
86 | struct list_head node; | 89 | struct list_head node; |
90 | struct dma_chan *chan_tx; | ||
91 | struct dma_chan *chan_rx; | ||
92 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | ||
93 | struct device *dma_dev; | ||
94 | enum sh_dmae_slave_chan_id slave_tx; | ||
95 | enum sh_dmae_slave_chan_id slave_rx; | ||
96 | struct dma_async_tx_descriptor *desc_tx; | ||
97 | struct dma_async_tx_descriptor *desc_rx[2]; | ||
98 | dma_cookie_t cookie_tx; | ||
99 | dma_cookie_t cookie_rx[2]; | ||
100 | dma_cookie_t active_rx; | ||
101 | struct scatterlist sg_tx; | ||
102 | unsigned int sg_len_tx; | ||
103 | struct scatterlist sg_rx[2]; | ||
104 | size_t buf_len_rx; | ||
105 | struct sh_dmae_slave param_tx; | ||
106 | struct sh_dmae_slave param_rx; | ||
107 | struct work_struct work_tx; | ||
108 | struct work_struct work_rx; | ||
109 | struct timer_list rx_timer; | ||
110 | #endif | ||
87 | }; | 111 | }; |
88 | 112 | ||
89 | struct sh_sci_priv { | 113 | struct sh_sci_priv { |
@@ -269,29 +293,44 @@ static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) | |||
269 | defined(CONFIG_CPU_SUBTYPE_SH7780) || \ | 293 | defined(CONFIG_CPU_SUBTYPE_SH7780) || \ |
270 | defined(CONFIG_CPU_SUBTYPE_SH7785) || \ | 294 | defined(CONFIG_CPU_SUBTYPE_SH7785) || \ |
271 | defined(CONFIG_CPU_SUBTYPE_SH7786) | 295 | defined(CONFIG_CPU_SUBTYPE_SH7786) |
272 | static inline int scif_txroom(struct uart_port *port) | 296 | static int scif_txfill(struct uart_port *port) |
273 | { | 297 | { |
274 | return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0xff); | 298 | return sci_in(port, SCTFDR) & 0xff; |
275 | } | 299 | } |
276 | 300 | ||
277 | static inline int scif_rxroom(struct uart_port *port) | 301 | static int scif_txroom(struct uart_port *port) |
302 | { | ||
303 | return SCIF_TXROOM_MAX - scif_txfill(port); | ||
304 | } | ||
305 | |||
306 | static int scif_rxfill(struct uart_port *port) | ||
278 | { | 307 | { |
279 | return sci_in(port, SCRFDR) & 0xff; | 308 | return sci_in(port, SCRFDR) & 0xff; |
280 | } | 309 | } |
281 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) | 310 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) |
282 | static inline int scif_txroom(struct uart_port *port) | 311 | static int scif_txfill(struct uart_port *port) |
283 | { | 312 | { |
284 | if ((port->mapbase == 0xffe00000) || | 313 | if (port->mapbase == 0xffe00000 || |
285 | (port->mapbase == 0xffe08000)) { | 314 | port->mapbase == 0xffe08000) |
286 | /* SCIF0/1*/ | 315 | /* SCIF0/1*/ |
287 | return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0xff); | 316 | return sci_in(port, SCTFDR) & 0xff; |
288 | } else { | 317 | else |
289 | /* SCIF2 */ | 318 | /* SCIF2 */ |
290 | return SCIF2_TXROOM_MAX - (sci_in(port, SCFDR) >> 8); | 319 | return sci_in(port, SCFDR) >> 8; |
291 | } | ||
292 | } | 320 | } |
293 | 321 | ||
294 | static inline int scif_rxroom(struct uart_port *port) | 322 | static int scif_txroom(struct uart_port *port) |
323 | { | ||
324 | if (port->mapbase == 0xffe00000 || | ||
325 | port->mapbase == 0xffe08000) | ||
326 | /* SCIF0/1*/ | ||
327 | return SCIF_TXROOM_MAX - scif_txfill(port); | ||
328 | else | ||
329 | /* SCIF2 */ | ||
330 | return SCIF2_TXROOM_MAX - scif_txfill(port); | ||
331 | } | ||
332 | |||
333 | static int scif_rxfill(struct uart_port *port) | ||
295 | { | 334 | { |
296 | if ((port->mapbase == 0xffe00000) || | 335 | if ((port->mapbase == 0xffe00000) || |
297 | (port->mapbase == 0xffe08000)) { | 336 | (port->mapbase == 0xffe08000)) { |
@@ -303,23 +342,33 @@ static inline int scif_rxroom(struct uart_port *port) | |||
303 | } | 342 | } |
304 | } | 343 | } |
305 | #else | 344 | #else |
306 | static inline int scif_txroom(struct uart_port *port) | 345 | static int scif_txfill(struct uart_port *port) |
346 | { | ||
347 | return sci_in(port, SCFDR) >> 8; | ||
348 | } | ||
349 | |||
350 | static int scif_txroom(struct uart_port *port) | ||
307 | { | 351 | { |
308 | return SCIF_TXROOM_MAX - (sci_in(port, SCFDR) >> 8); | 352 | return SCIF_TXROOM_MAX - scif_txfill(port); |
309 | } | 353 | } |
310 | 354 | ||
311 | static inline int scif_rxroom(struct uart_port *port) | 355 | static int scif_rxfill(struct uart_port *port) |
312 | { | 356 | { |
313 | return sci_in(port, SCFDR) & SCIF_RFDC_MASK; | 357 | return sci_in(port, SCFDR) & SCIF_RFDC_MASK; |
314 | } | 358 | } |
315 | #endif | 359 | #endif |
316 | 360 | ||
317 | static inline int sci_txroom(struct uart_port *port) | 361 | static int sci_txfill(struct uart_port *port) |
318 | { | 362 | { |
319 | return (sci_in(port, SCxSR) & SCI_TDRE) != 0; | 363 | return !(sci_in(port, SCxSR) & SCI_TDRE); |
320 | } | 364 | } |
321 | 365 | ||
322 | static inline int sci_rxroom(struct uart_port *port) | 366 | static int sci_txroom(struct uart_port *port) |
367 | { | ||
368 | return !sci_txfill(port); | ||
369 | } | ||
370 | |||
371 | static int sci_rxfill(struct uart_port *port) | ||
323 | { | 372 | { |
324 | return (sci_in(port, SCxSR) & SCxSR_RDxF(port)) != 0; | 373 | return (sci_in(port, SCxSR) & SCxSR_RDxF(port)) != 0; |
325 | } | 374 | } |
@@ -406,9 +455,9 @@ static inline void sci_receive_chars(struct uart_port *port) | |||
406 | 455 | ||
407 | while (1) { | 456 | while (1) { |
408 | if (port->type == PORT_SCI) | 457 | if (port->type == PORT_SCI) |
409 | count = sci_rxroom(port); | 458 | count = sci_rxfill(port); |
410 | else | 459 | else |
411 | count = scif_rxroom(port); | 460 | count = scif_rxfill(port); |
412 | 461 | ||
413 | /* Don't copy more bytes than there is room for in the buffer */ | 462 | /* Don't copy more bytes than there is room for in the buffer */ |
414 | count = tty_buffer_request_room(tty, count); | 463 | count = tty_buffer_request_room(tty, count); |
@@ -453,10 +502,10 @@ static inline void sci_receive_chars(struct uart_port *port) | |||
453 | } | 502 | } |
454 | 503 | ||
455 | /* Store data and status */ | 504 | /* Store data and status */ |
456 | if (status&SCxSR_FER(port)) { | 505 | if (status & SCxSR_FER(port)) { |
457 | flag = TTY_FRAME; | 506 | flag = TTY_FRAME; |
458 | dev_notice(port->dev, "frame error\n"); | 507 | dev_notice(port->dev, "frame error\n"); |
459 | } else if (status&SCxSR_PER(port)) { | 508 | } else if (status & SCxSR_PER(port)) { |
460 | flag = TTY_PARITY; | 509 | flag = TTY_PARITY; |
461 | dev_notice(port->dev, "parity error\n"); | 510 | dev_notice(port->dev, "parity error\n"); |
462 | } else | 511 | } else |
@@ -618,13 +667,39 @@ static inline int sci_handle_breaks(struct uart_port *port) | |||
618 | return copied; | 667 | return copied; |
619 | } | 668 | } |
620 | 669 | ||
621 | static irqreturn_t sci_rx_interrupt(int irq, void *port) | 670 | static irqreturn_t sci_rx_interrupt(int irq, void *ptr) |
622 | { | 671 | { |
672 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | ||
673 | struct uart_port *port = ptr; | ||
674 | struct sci_port *s = to_sci_port(port); | ||
675 | |||
676 | if (s->chan_rx) { | ||
677 | unsigned long tout; | ||
678 | u16 scr = sci_in(port, SCSCR); | ||
679 | u16 ssr = sci_in(port, SCxSR); | ||
680 | |||
681 | /* Disable future Rx interrupts */ | ||
682 | sci_out(port, SCSCR, scr & ~SCI_CTRL_FLAGS_RIE); | ||
683 | /* Clear current interrupt */ | ||
684 | sci_out(port, SCxSR, ssr & ~(1 | SCxSR_RDxF(port))); | ||
685 | /* Calculate delay for 1.5 DMA buffers */ | ||
686 | tout = (port->timeout - HZ / 50) * s->buf_len_rx * 3 / | ||
687 | port->fifosize / 2; | ||
688 | dev_dbg(port->dev, "Rx IRQ: setup timeout in %lu ms\n", | ||
689 | tout * 1000 / HZ); | ||
690 | if (tout < 2) | ||
691 | tout = 2; | ||
692 | mod_timer(&s->rx_timer, jiffies + tout); | ||
693 | |||
694 | return IRQ_HANDLED; | ||
695 | } | ||
696 | #endif | ||
697 | |||
623 | /* I think sci_receive_chars has to be called irrespective | 698 | /* I think sci_receive_chars has to be called irrespective |
624 | * of whether the I_IXOFF is set, otherwise, how is the interrupt | 699 | * of whether the I_IXOFF is set, otherwise, how is the interrupt |
625 | * to be disabled? | 700 | * to be disabled? |
626 | */ | 701 | */ |
627 | sci_receive_chars(port); | 702 | sci_receive_chars(ptr); |
628 | 703 | ||
629 | return IRQ_HANDLED; | 704 | return IRQ_HANDLED; |
630 | } | 705 | } |
@@ -680,6 +755,7 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) | |||
680 | { | 755 | { |
681 | unsigned short ssr_status, scr_status, err_enabled; | 756 | unsigned short ssr_status, scr_status, err_enabled; |
682 | struct uart_port *port = ptr; | 757 | struct uart_port *port = ptr; |
758 | struct sci_port *s = to_sci_port(port); | ||
683 | irqreturn_t ret = IRQ_NONE; | 759 | irqreturn_t ret = IRQ_NONE; |
684 | 760 | ||
685 | ssr_status = sci_in(port, SCxSR); | 761 | ssr_status = sci_in(port, SCxSR); |
@@ -687,10 +763,15 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) | |||
687 | err_enabled = scr_status & (SCI_CTRL_FLAGS_REIE | SCI_CTRL_FLAGS_RIE); | 763 | err_enabled = scr_status & (SCI_CTRL_FLAGS_REIE | SCI_CTRL_FLAGS_RIE); |
688 | 764 | ||
689 | /* Tx Interrupt */ | 765 | /* Tx Interrupt */ |
690 | if ((ssr_status & SCxSR_TDxE(port)) && (scr_status & SCI_CTRL_FLAGS_TIE)) | 766 | if ((ssr_status & SCxSR_TDxE(port)) && (scr_status & SCI_CTRL_FLAGS_TIE) && |
767 | !s->chan_tx) | ||
691 | ret = sci_tx_interrupt(irq, ptr); | 768 | ret = sci_tx_interrupt(irq, ptr); |
692 | /* Rx Interrupt */ | 769 | /* |
693 | if ((ssr_status & SCxSR_RDxF(port)) && (scr_status & SCI_CTRL_FLAGS_RIE)) | 770 | * Rx Interrupt: if we're using DMA, the DMA controller clears RDF / |
771 | * DR flags | ||
772 | */ | ||
773 | if (((ssr_status & SCxSR_RDxF(port)) || s->chan_rx) && | ||
774 | (scr_status & SCI_CTRL_FLAGS_RIE)) | ||
694 | ret = sci_rx_interrupt(irq, ptr); | 775 | ret = sci_rx_interrupt(irq, ptr); |
695 | /* Error Interrupt */ | 776 | /* Error Interrupt */ |
696 | if ((ssr_status & SCxSR_ERRORS(port)) && err_enabled) | 777 | if ((ssr_status & SCxSR_ERRORS(port)) && err_enabled) |
@@ -699,6 +780,10 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) | |||
699 | if ((ssr_status & SCxSR_BRK(port)) && err_enabled) | 780 | if ((ssr_status & SCxSR_BRK(port)) && err_enabled) |
700 | ret = sci_br_interrupt(irq, ptr); | 781 | ret = sci_br_interrupt(irq, ptr); |
701 | 782 | ||
783 | WARN_ONCE(ret == IRQ_NONE, | ||
784 | "%s: %d IRQ %d, status %x, control %x\n", __func__, | ||
785 | irq, port->line, ssr_status, scr_status); | ||
786 | |||
702 | return ret; | 787 | return ret; |
703 | } | 788 | } |
704 | 789 | ||
@@ -800,7 +885,9 @@ static void sci_free_irq(struct sci_port *port) | |||
800 | static unsigned int sci_tx_empty(struct uart_port *port) | 885 | static unsigned int sci_tx_empty(struct uart_port *port) |
801 | { | 886 | { |
802 | unsigned short status = sci_in(port, SCxSR); | 887 | unsigned short status = sci_in(port, SCxSR); |
803 | return status & SCxSR_TEND(port) ? TIOCSER_TEMT : 0; | 888 | unsigned short in_tx_fifo = scif_txfill(port); |
889 | |||
890 | return (status & SCxSR_TEND(port)) && !in_tx_fifo ? TIOCSER_TEMT : 0; | ||
804 | } | 891 | } |
805 | 892 | ||
806 | static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl) | 893 | static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl) |
@@ -812,16 +899,297 @@ static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
812 | 899 | ||
813 | static unsigned int sci_get_mctrl(struct uart_port *port) | 900 | static unsigned int sci_get_mctrl(struct uart_port *port) |
814 | { | 901 | { |
815 | /* This routine is used for geting signals of: DTR, DCD, DSR, RI, | 902 | /* This routine is used for getting signals of: DTR, DCD, DSR, RI, |
816 | and CTS/RTS */ | 903 | and CTS/RTS */ |
817 | 904 | ||
818 | return TIOCM_DTR | TIOCM_RTS | TIOCM_DSR; | 905 | return TIOCM_DTR | TIOCM_RTS | TIOCM_DSR; |
819 | } | 906 | } |
820 | 907 | ||
908 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | ||
909 | static void sci_dma_tx_complete(void *arg) | ||
910 | { | ||
911 | struct sci_port *s = arg; | ||
912 | struct uart_port *port = &s->port; | ||
913 | struct circ_buf *xmit = &port->state->xmit; | ||
914 | unsigned long flags; | ||
915 | |||
916 | dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); | ||
917 | |||
918 | spin_lock_irqsave(&port->lock, flags); | ||
919 | |||
920 | xmit->tail += s->sg_tx.length; | ||
921 | xmit->tail &= UART_XMIT_SIZE - 1; | ||
922 | |||
923 | port->icount.tx += s->sg_tx.length; | ||
924 | |||
925 | async_tx_ack(s->desc_tx); | ||
926 | s->cookie_tx = -EINVAL; | ||
927 | s->desc_tx = NULL; | ||
928 | |||
929 | spin_unlock_irqrestore(&port->lock, flags); | ||
930 | |||
931 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
932 | uart_write_wakeup(port); | ||
933 | |||
934 | if (uart_circ_chars_pending(xmit)) | ||
935 | schedule_work(&s->work_tx); | ||
936 | } | ||
937 | |||
938 | /* Locking: called with port lock held */ | ||
939 | static int sci_dma_rx_push(struct sci_port *s, struct tty_struct *tty, | ||
940 | size_t count) | ||
941 | { | ||
942 | struct uart_port *port = &s->port; | ||
943 | int i, active, room; | ||
944 | |||
945 | room = tty_buffer_request_room(tty, count); | ||
946 | |||
947 | if (s->active_rx == s->cookie_rx[0]) { | ||
948 | active = 0; | ||
949 | } else if (s->active_rx == s->cookie_rx[1]) { | ||
950 | active = 1; | ||
951 | } else { | ||
952 | dev_err(port->dev, "cookie %d not found!\n", s->active_rx); | ||
953 | return 0; | ||
954 | } | ||
955 | |||
956 | if (room < count) | ||
957 | dev_warn(port->dev, "Rx overrun: dropping %u bytes\n", | ||
958 | count - room); | ||
959 | if (!room) | ||
960 | return room; | ||
961 | |||
962 | for (i = 0; i < room; i++) | ||
963 | tty_insert_flip_char(tty, ((u8 *)sg_virt(&s->sg_rx[active]))[i], | ||
964 | TTY_NORMAL); | ||
965 | |||
966 | port->icount.rx += room; | ||
967 | |||
968 | return room; | ||
969 | } | ||
970 | |||
971 | static void sci_dma_rx_complete(void *arg) | ||
972 | { | ||
973 | struct sci_port *s = arg; | ||
974 | struct uart_port *port = &s->port; | ||
975 | struct tty_struct *tty = port->state->port.tty; | ||
976 | unsigned long flags; | ||
977 | int count; | ||
978 | |||
979 | dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); | ||
980 | |||
981 | spin_lock_irqsave(&port->lock, flags); | ||
982 | |||
983 | count = sci_dma_rx_push(s, tty, s->buf_len_rx); | ||
984 | |||
985 | mod_timer(&s->rx_timer, jiffies + msecs_to_jiffies(5)); | ||
986 | |||
987 | spin_unlock_irqrestore(&port->lock, flags); | ||
988 | |||
989 | if (count) | ||
990 | tty_flip_buffer_push(tty); | ||
991 | |||
992 | schedule_work(&s->work_rx); | ||
993 | } | ||
994 | |||
995 | static void sci_start_rx(struct uart_port *port); | ||
996 | static void sci_start_tx(struct uart_port *port); | ||
997 | |||
998 | static void sci_rx_dma_release(struct sci_port *s, bool enable_pio) | ||
999 | { | ||
1000 | struct dma_chan *chan = s->chan_rx; | ||
1001 | struct uart_port *port = &s->port; | ||
1002 | |||
1003 | s->chan_rx = NULL; | ||
1004 | s->cookie_rx[0] = s->cookie_rx[1] = -EINVAL; | ||
1005 | dma_release_channel(chan); | ||
1006 | dma_free_coherent(port->dev, s->buf_len_rx * 2, | ||
1007 | sg_virt(&s->sg_rx[0]), sg_dma_address(&s->sg_rx[0])); | ||
1008 | if (enable_pio) | ||
1009 | sci_start_rx(port); | ||
1010 | } | ||
1011 | |||
1012 | static void sci_tx_dma_release(struct sci_port *s, bool enable_pio) | ||
1013 | { | ||
1014 | struct dma_chan *chan = s->chan_tx; | ||
1015 | struct uart_port *port = &s->port; | ||
1016 | |||
1017 | s->chan_tx = NULL; | ||
1018 | s->cookie_tx = -EINVAL; | ||
1019 | dma_release_channel(chan); | ||
1020 | if (enable_pio) | ||
1021 | sci_start_tx(port); | ||
1022 | } | ||
1023 | |||
1024 | static void sci_submit_rx(struct sci_port *s) | ||
1025 | { | ||
1026 | struct dma_chan *chan = s->chan_rx; | ||
1027 | int i; | ||
1028 | |||
1029 | for (i = 0; i < 2; i++) { | ||
1030 | struct scatterlist *sg = &s->sg_rx[i]; | ||
1031 | struct dma_async_tx_descriptor *desc; | ||
1032 | |||
1033 | desc = chan->device->device_prep_slave_sg(chan, | ||
1034 | sg, 1, DMA_FROM_DEVICE, DMA_PREP_INTERRUPT); | ||
1035 | |||
1036 | if (desc) { | ||
1037 | s->desc_rx[i] = desc; | ||
1038 | desc->callback = sci_dma_rx_complete; | ||
1039 | desc->callback_param = s; | ||
1040 | s->cookie_rx[i] = desc->tx_submit(desc); | ||
1041 | } | ||
1042 | |||
1043 | if (!desc || s->cookie_rx[i] < 0) { | ||
1044 | if (i) { | ||
1045 | async_tx_ack(s->desc_rx[0]); | ||
1046 | s->cookie_rx[0] = -EINVAL; | ||
1047 | } | ||
1048 | if (desc) { | ||
1049 | async_tx_ack(desc); | ||
1050 | s->cookie_rx[i] = -EINVAL; | ||
1051 | } | ||
1052 | dev_warn(s->port.dev, | ||
1053 | "failed to re-start DMA, using PIO\n"); | ||
1054 | sci_rx_dma_release(s, true); | ||
1055 | return; | ||
1056 | } | ||
1057 | } | ||
1058 | |||
1059 | s->active_rx = s->cookie_rx[0]; | ||
1060 | |||
1061 | dma_async_issue_pending(chan); | ||
1062 | } | ||
1063 | |||
1064 | static void work_fn_rx(struct work_struct *work) | ||
1065 | { | ||
1066 | struct sci_port *s = container_of(work, struct sci_port, work_rx); | ||
1067 | struct uart_port *port = &s->port; | ||
1068 | struct dma_async_tx_descriptor *desc; | ||
1069 | int new; | ||
1070 | |||
1071 | if (s->active_rx == s->cookie_rx[0]) { | ||
1072 | new = 0; | ||
1073 | } else if (s->active_rx == s->cookie_rx[1]) { | ||
1074 | new = 1; | ||
1075 | } else { | ||
1076 | dev_err(port->dev, "cookie %d not found!\n", s->active_rx); | ||
1077 | return; | ||
1078 | } | ||
1079 | desc = s->desc_rx[new]; | ||
1080 | |||
1081 | if (dma_async_is_tx_complete(s->chan_rx, s->active_rx, NULL, NULL) != | ||
1082 | DMA_SUCCESS) { | ||
1083 | /* Handle incomplete DMA receive */ | ||
1084 | struct tty_struct *tty = port->state->port.tty; | ||
1085 | struct dma_chan *chan = s->chan_rx; | ||
1086 | struct sh_desc *sh_desc = container_of(desc, struct sh_desc, | ||
1087 | async_tx); | ||
1088 | unsigned long flags; | ||
1089 | int count; | ||
1090 | |||
1091 | chan->device->device_terminate_all(chan); | ||
1092 | dev_dbg(port->dev, "Read %u bytes with cookie %d\n", | ||
1093 | sh_desc->partial, sh_desc->cookie); | ||
1094 | |||
1095 | spin_lock_irqsave(&port->lock, flags); | ||
1096 | count = sci_dma_rx_push(s, tty, sh_desc->partial); | ||
1097 | spin_unlock_irqrestore(&port->lock, flags); | ||
1098 | |||
1099 | if (count) | ||
1100 | tty_flip_buffer_push(tty); | ||
1101 | |||
1102 | sci_submit_rx(s); | ||
1103 | |||
1104 | return; | ||
1105 | } | ||
1106 | |||
1107 | s->cookie_rx[new] = desc->tx_submit(desc); | ||
1108 | if (s->cookie_rx[new] < 0) { | ||
1109 | dev_warn(port->dev, "Failed submitting Rx DMA descriptor\n"); | ||
1110 | sci_rx_dma_release(s, true); | ||
1111 | return; | ||
1112 | } | ||
1113 | |||
1114 | dev_dbg(port->dev, "%s: cookie %d #%d\n", __func__, | ||
1115 | s->cookie_rx[new], new); | ||
1116 | |||
1117 | s->active_rx = s->cookie_rx[!new]; | ||
1118 | } | ||
1119 | |||
1120 | static void work_fn_tx(struct work_struct *work) | ||
1121 | { | ||
1122 | struct sci_port *s = container_of(work, struct sci_port, work_tx); | ||
1123 | struct dma_async_tx_descriptor *desc; | ||
1124 | struct dma_chan *chan = s->chan_tx; | ||
1125 | struct uart_port *port = &s->port; | ||
1126 | struct circ_buf *xmit = &port->state->xmit; | ||
1127 | struct scatterlist *sg = &s->sg_tx; | ||
1128 | |||
1129 | /* | ||
1130 | * DMA is idle now. | ||
1131 | * Port xmit buffer is already mapped, and it is one page... Just adjust | ||
1132 | * offsets and lengths. Since it is a circular buffer, we have to | ||
1133 | * transmit till the end, and then the rest. Take the port lock to get a | ||
1134 | * consistent xmit buffer state. | ||
1135 | */ | ||
1136 | spin_lock_irq(&port->lock); | ||
1137 | sg->offset = xmit->tail & (UART_XMIT_SIZE - 1); | ||
1138 | sg->dma_address = (sg_dma_address(sg) & ~(UART_XMIT_SIZE - 1)) + | ||
1139 | sg->offset; | ||
1140 | sg->length = min((int)CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE), | ||
1141 | CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE)); | ||
1142 | sg->dma_length = sg->length; | ||
1143 | spin_unlock_irq(&port->lock); | ||
1144 | |||
1145 | BUG_ON(!sg->length); | ||
1146 | |||
1147 | desc = chan->device->device_prep_slave_sg(chan, | ||
1148 | sg, s->sg_len_tx, DMA_TO_DEVICE, | ||
1149 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
1150 | if (!desc) { | ||
1151 | /* switch to PIO */ | ||
1152 | sci_tx_dma_release(s, true); | ||
1153 | return; | ||
1154 | } | ||
1155 | |||
1156 | dma_sync_sg_for_device(port->dev, sg, 1, DMA_TO_DEVICE); | ||
1157 | |||
1158 | spin_lock_irq(&port->lock); | ||
1159 | s->desc_tx = desc; | ||
1160 | desc->callback = sci_dma_tx_complete; | ||
1161 | desc->callback_param = s; | ||
1162 | spin_unlock_irq(&port->lock); | ||
1163 | s->cookie_tx = desc->tx_submit(desc); | ||
1164 | if (s->cookie_tx < 0) { | ||
1165 | dev_warn(port->dev, "Failed submitting Tx DMA descriptor\n"); | ||
1166 | /* switch to PIO */ | ||
1167 | sci_tx_dma_release(s, true); | ||
1168 | return; | ||
1169 | } | ||
1170 | |||
1171 | dev_dbg(port->dev, "%s: %p: %d...%d, cookie %d\n", __func__, | ||
1172 | xmit->buf, xmit->tail, xmit->head, s->cookie_tx); | ||
1173 | |||
1174 | dma_async_issue_pending(chan); | ||
1175 | } | ||
1176 | #endif | ||
1177 | |||
821 | static void sci_start_tx(struct uart_port *port) | 1178 | static void sci_start_tx(struct uart_port *port) |
822 | { | 1179 | { |
823 | unsigned short ctrl; | 1180 | unsigned short ctrl; |
824 | 1181 | ||
1182 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | ||
1183 | struct sci_port *s = to_sci_port(port); | ||
1184 | |||
1185 | if (s->chan_tx) { | ||
1186 | if (!uart_circ_empty(&s->port.state->xmit) && s->cookie_tx < 0) | ||
1187 | schedule_work(&s->work_tx); | ||
1188 | |||
1189 | return; | ||
1190 | } | ||
1191 | #endif | ||
1192 | |||
825 | /* Set TIE (Transmit Interrupt Enable) bit in SCSCR */ | 1193 | /* Set TIE (Transmit Interrupt Enable) bit in SCSCR */ |
826 | ctrl = sci_in(port, SCSCR); | 1194 | ctrl = sci_in(port, SCSCR); |
827 | ctrl |= SCI_CTRL_FLAGS_TIE; | 1195 | ctrl |= SCI_CTRL_FLAGS_TIE; |
@@ -838,13 +1206,12 @@ static void sci_stop_tx(struct uart_port *port) | |||
838 | sci_out(port, SCSCR, ctrl); | 1206 | sci_out(port, SCSCR, ctrl); |
839 | } | 1207 | } |
840 | 1208 | ||
841 | static void sci_start_rx(struct uart_port *port, unsigned int tty_start) | 1209 | static void sci_start_rx(struct uart_port *port) |
842 | { | 1210 | { |
843 | unsigned short ctrl; | 1211 | unsigned short ctrl = SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE; |
844 | 1212 | ||
845 | /* Set RIE (Receive Interrupt Enable) bit in SCSCR */ | 1213 | /* Set RIE (Receive Interrupt Enable) bit in SCSCR */ |
846 | ctrl = sci_in(port, SCSCR); | 1214 | ctrl |= sci_in(port, SCSCR); |
847 | ctrl |= SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE; | ||
848 | sci_out(port, SCSCR, ctrl); | 1215 | sci_out(port, SCSCR, ctrl); |
849 | } | 1216 | } |
850 | 1217 | ||
@@ -868,16 +1235,154 @@ static void sci_break_ctl(struct uart_port *port, int break_state) | |||
868 | /* Nothing here yet .. */ | 1235 | /* Nothing here yet .. */ |
869 | } | 1236 | } |
870 | 1237 | ||
1238 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | ||
1239 | static bool filter(struct dma_chan *chan, void *slave) | ||
1240 | { | ||
1241 | struct sh_dmae_slave *param = slave; | ||
1242 | |||
1243 | dev_dbg(chan->device->dev, "%s: slave ID %d\n", __func__, | ||
1244 | param->slave_id); | ||
1245 | |||
1246 | if (param->dma_dev == chan->device->dev) { | ||
1247 | chan->private = param; | ||
1248 | return true; | ||
1249 | } else { | ||
1250 | return false; | ||
1251 | } | ||
1252 | } | ||
1253 | |||
1254 | static void rx_timer_fn(unsigned long arg) | ||
1255 | { | ||
1256 | struct sci_port *s = (struct sci_port *)arg; | ||
1257 | struct uart_port *port = &s->port; | ||
1258 | |||
1259 | u16 scr = sci_in(port, SCSCR); | ||
1260 | sci_out(port, SCSCR, scr | SCI_CTRL_FLAGS_RIE); | ||
1261 | dev_dbg(port->dev, "DMA Rx timed out\n"); | ||
1262 | schedule_work(&s->work_rx); | ||
1263 | } | ||
1264 | |||
1265 | static void sci_request_dma(struct uart_port *port) | ||
1266 | { | ||
1267 | struct sci_port *s = to_sci_port(port); | ||
1268 | struct sh_dmae_slave *param; | ||
1269 | struct dma_chan *chan; | ||
1270 | dma_cap_mask_t mask; | ||
1271 | int nent; | ||
1272 | |||
1273 | dev_dbg(port->dev, "%s: port %d DMA %p\n", __func__, | ||
1274 | port->line, s->dma_dev); | ||
1275 | |||
1276 | if (!s->dma_dev) | ||
1277 | return; | ||
1278 | |||
1279 | dma_cap_zero(mask); | ||
1280 | dma_cap_set(DMA_SLAVE, mask); | ||
1281 | |||
1282 | param = &s->param_tx; | ||
1283 | |||
1284 | /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_TX */ | ||
1285 | param->slave_id = s->slave_tx; | ||
1286 | param->dma_dev = s->dma_dev; | ||
1287 | |||
1288 | s->cookie_tx = -EINVAL; | ||
1289 | chan = dma_request_channel(mask, filter, param); | ||
1290 | dev_dbg(port->dev, "%s: TX: got channel %p\n", __func__, chan); | ||
1291 | if (chan) { | ||
1292 | s->chan_tx = chan; | ||
1293 | sg_init_table(&s->sg_tx, 1); | ||
1294 | /* UART circular tx buffer is an aligned page. */ | ||
1295 | BUG_ON((int)port->state->xmit.buf & ~PAGE_MASK); | ||
1296 | sg_set_page(&s->sg_tx, virt_to_page(port->state->xmit.buf), | ||
1297 | UART_XMIT_SIZE, (int)port->state->xmit.buf & ~PAGE_MASK); | ||
1298 | nent = dma_map_sg(port->dev, &s->sg_tx, 1, DMA_TO_DEVICE); | ||
1299 | if (!nent) | ||
1300 | sci_tx_dma_release(s, false); | ||
1301 | else | ||
1302 | dev_dbg(port->dev, "%s: mapped %d@%p to %x\n", __func__, | ||
1303 | sg_dma_len(&s->sg_tx), | ||
1304 | port->state->xmit.buf, sg_dma_address(&s->sg_tx)); | ||
1305 | |||
1306 | s->sg_len_tx = nent; | ||
1307 | |||
1308 | INIT_WORK(&s->work_tx, work_fn_tx); | ||
1309 | } | ||
1310 | |||
1311 | param = &s->param_rx; | ||
1312 | |||
1313 | /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_RX */ | ||
1314 | param->slave_id = s->slave_rx; | ||
1315 | param->dma_dev = s->dma_dev; | ||
1316 | |||
1317 | chan = dma_request_channel(mask, filter, param); | ||
1318 | dev_dbg(port->dev, "%s: RX: got channel %p\n", __func__, chan); | ||
1319 | if (chan) { | ||
1320 | dma_addr_t dma[2]; | ||
1321 | void *buf[2]; | ||
1322 | int i; | ||
1323 | |||
1324 | s->chan_rx = chan; | ||
1325 | |||
1326 | s->buf_len_rx = 2 * max(16, (int)port->fifosize); | ||
1327 | buf[0] = dma_alloc_coherent(port->dev, s->buf_len_rx * 2, | ||
1328 | &dma[0], GFP_KERNEL); | ||
1329 | |||
1330 | if (!buf[0]) { | ||
1331 | dev_warn(port->dev, | ||
1332 | "failed to allocate dma buffer, using PIO\n"); | ||
1333 | sci_rx_dma_release(s, true); | ||
1334 | return; | ||
1335 | } | ||
1336 | |||
1337 | buf[1] = buf[0] + s->buf_len_rx; | ||
1338 | dma[1] = dma[0] + s->buf_len_rx; | ||
1339 | |||
1340 | for (i = 0; i < 2; i++) { | ||
1341 | struct scatterlist *sg = &s->sg_rx[i]; | ||
1342 | |||
1343 | sg_init_table(sg, 1); | ||
1344 | sg_set_page(sg, virt_to_page(buf[i]), s->buf_len_rx, | ||
1345 | (int)buf[i] & ~PAGE_MASK); | ||
1346 | sg->dma_address = dma[i]; | ||
1347 | sg->dma_length = sg->length; | ||
1348 | } | ||
1349 | |||
1350 | INIT_WORK(&s->work_rx, work_fn_rx); | ||
1351 | setup_timer(&s->rx_timer, rx_timer_fn, (unsigned long)s); | ||
1352 | |||
1353 | sci_submit_rx(s); | ||
1354 | } | ||
1355 | } | ||
1356 | |||
1357 | static void sci_free_dma(struct uart_port *port) | ||
1358 | { | ||
1359 | struct sci_port *s = to_sci_port(port); | ||
1360 | |||
1361 | if (!s->dma_dev) | ||
1362 | return; | ||
1363 | |||
1364 | if (s->chan_tx) | ||
1365 | sci_tx_dma_release(s, false); | ||
1366 | if (s->chan_rx) | ||
1367 | sci_rx_dma_release(s, false); | ||
1368 | } | ||
1369 | #endif | ||
1370 | |||
871 | static int sci_startup(struct uart_port *port) | 1371 | static int sci_startup(struct uart_port *port) |
872 | { | 1372 | { |
873 | struct sci_port *s = to_sci_port(port); | 1373 | struct sci_port *s = to_sci_port(port); |
874 | 1374 | ||
1375 | dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); | ||
1376 | |||
875 | if (s->enable) | 1377 | if (s->enable) |
876 | s->enable(port); | 1378 | s->enable(port); |
877 | 1379 | ||
878 | sci_request_irq(s); | 1380 | sci_request_irq(s); |
1381 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | ||
1382 | sci_request_dma(port); | ||
1383 | #endif | ||
879 | sci_start_tx(port); | 1384 | sci_start_tx(port); |
880 | sci_start_rx(port, 1); | 1385 | sci_start_rx(port); |
881 | 1386 | ||
882 | return 0; | 1387 | return 0; |
883 | } | 1388 | } |
@@ -886,8 +1391,13 @@ static void sci_shutdown(struct uart_port *port) | |||
886 | { | 1391 | { |
887 | struct sci_port *s = to_sci_port(port); | 1392 | struct sci_port *s = to_sci_port(port); |
888 | 1393 | ||
1394 | dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); | ||
1395 | |||
889 | sci_stop_rx(port); | 1396 | sci_stop_rx(port); |
890 | sci_stop_tx(port); | 1397 | sci_stop_tx(port); |
1398 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | ||
1399 | sci_free_dma(port); | ||
1400 | #endif | ||
891 | sci_free_irq(s); | 1401 | sci_free_irq(s); |
892 | 1402 | ||
893 | if (s->disable) | 1403 | if (s->disable) |
@@ -937,6 +1447,9 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
937 | 1447 | ||
938 | sci_out(port, SCSMR, smr_val); | 1448 | sci_out(port, SCSMR, smr_val); |
939 | 1449 | ||
1450 | dev_dbg(port->dev, "%s: SMR %x, t %x, SCSCR %x\n", __func__, smr_val, t, | ||
1451 | SCSCR_INIT(port)); | ||
1452 | |||
940 | if (t > 0) { | 1453 | if (t > 0) { |
941 | if (t >= 256) { | 1454 | if (t >= 256) { |
942 | sci_out(port, SCSMR, (sci_in(port, SCSMR) & ~3) | 1); | 1455 | sci_out(port, SCSMR, (sci_in(port, SCSMR) & ~3) | 1); |
@@ -954,7 +1467,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
954 | sci_out(port, SCSCR, SCSCR_INIT(port)); | 1467 | sci_out(port, SCSCR, SCSCR_INIT(port)); |
955 | 1468 | ||
956 | if ((termios->c_cflag & CREAD) != 0) | 1469 | if ((termios->c_cflag & CREAD) != 0) |
957 | sci_start_rx(port, 0); | 1470 | sci_start_rx(port); |
958 | } | 1471 | } |
959 | 1472 | ||
960 | static const char *sci_type(struct uart_port *port) | 1473 | static const char *sci_type(struct uart_port *port) |
@@ -1049,19 +1562,21 @@ static void __devinit sci_init_single(struct platform_device *dev, | |||
1049 | unsigned int index, | 1562 | unsigned int index, |
1050 | struct plat_sci_port *p) | 1563 | struct plat_sci_port *p) |
1051 | { | 1564 | { |
1052 | sci_port->port.ops = &sci_uart_ops; | 1565 | struct uart_port *port = &sci_port->port; |
1053 | sci_port->port.iotype = UPIO_MEM; | 1566 | |
1054 | sci_port->port.line = index; | 1567 | port->ops = &sci_uart_ops; |
1568 | port->iotype = UPIO_MEM; | ||
1569 | port->line = index; | ||
1055 | 1570 | ||
1056 | switch (p->type) { | 1571 | switch (p->type) { |
1057 | case PORT_SCIFA: | 1572 | case PORT_SCIFA: |
1058 | sci_port->port.fifosize = 64; | 1573 | port->fifosize = 64; |
1059 | break; | 1574 | break; |
1060 | case PORT_SCIF: | 1575 | case PORT_SCIF: |
1061 | sci_port->port.fifosize = 16; | 1576 | port->fifosize = 16; |
1062 | break; | 1577 | break; |
1063 | default: | 1578 | default: |
1064 | sci_port->port.fifosize = 1; | 1579 | port->fifosize = 1; |
1065 | break; | 1580 | break; |
1066 | } | 1581 | } |
1067 | 1582 | ||
@@ -1070,19 +1585,28 @@ static void __devinit sci_init_single(struct platform_device *dev, | |||
1070 | sci_port->dclk = clk_get(&dev->dev, "peripheral_clk"); | 1585 | sci_port->dclk = clk_get(&dev->dev, "peripheral_clk"); |
1071 | sci_port->enable = sci_clk_enable; | 1586 | sci_port->enable = sci_clk_enable; |
1072 | sci_port->disable = sci_clk_disable; | 1587 | sci_port->disable = sci_clk_disable; |
1073 | sci_port->port.dev = &dev->dev; | 1588 | port->dev = &dev->dev; |
1074 | } | 1589 | } |
1075 | 1590 | ||
1076 | sci_port->break_timer.data = (unsigned long)sci_port; | 1591 | sci_port->break_timer.data = (unsigned long)sci_port; |
1077 | sci_port->break_timer.function = sci_break_timer; | 1592 | sci_port->break_timer.function = sci_break_timer; |
1078 | init_timer(&sci_port->break_timer); | 1593 | init_timer(&sci_port->break_timer); |
1079 | 1594 | ||
1080 | sci_port->port.mapbase = p->mapbase; | 1595 | port->mapbase = p->mapbase; |
1081 | sci_port->port.membase = p->membase; | 1596 | port->membase = p->membase; |
1082 | 1597 | ||
1083 | sci_port->port.irq = p->irqs[SCIx_TXI_IRQ]; | 1598 | port->irq = p->irqs[SCIx_TXI_IRQ]; |
1084 | sci_port->port.flags = p->flags; | 1599 | port->flags = p->flags; |
1085 | sci_port->type = sci_port->port.type = p->type; | 1600 | sci_port->type = port->type = p->type; |
1601 | |||
1602 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | ||
1603 | sci_port->dma_dev = p->dma_dev; | ||
1604 | sci_port->slave_tx = p->dma_slave_tx; | ||
1605 | sci_port->slave_rx = p->dma_slave_rx; | ||
1606 | |||
1607 | dev_dbg(port->dev, "%s: DMA device %p, tx %d, rx %d\n", __func__, | ||
1608 | p->dma_dev, p->dma_slave_tx, p->dma_slave_rx); | ||
1609 | #endif | ||
1086 | 1610 | ||
1087 | memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs)); | 1611 | memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs)); |
1088 | } | 1612 | } |
diff --git a/drivers/serial/timbuart.c b/drivers/serial/timbuart.c index 34b31da01d09..7bf10264a6ac 100644 --- a/drivers/serial/timbuart.c +++ b/drivers/serial/timbuart.c | |||
@@ -421,7 +421,7 @@ static struct uart_driver timbuart_driver = { | |||
421 | 421 | ||
422 | static int timbuart_probe(struct platform_device *dev) | 422 | static int timbuart_probe(struct platform_device *dev) |
423 | { | 423 | { |
424 | int err; | 424 | int err, irq; |
425 | struct timbuart_port *uart; | 425 | struct timbuart_port *uart; |
426 | struct resource *iomem; | 426 | struct resource *iomem; |
427 | 427 | ||
@@ -453,11 +453,12 @@ static int timbuart_probe(struct platform_device *dev) | |||
453 | uart->port.mapbase = iomem->start; | 453 | uart->port.mapbase = iomem->start; |
454 | uart->port.membase = NULL; | 454 | uart->port.membase = NULL; |
455 | 455 | ||
456 | uart->port.irq = platform_get_irq(dev, 0); | 456 | irq = platform_get_irq(dev, 0); |
457 | if (uart->port.irq < 0) { | 457 | if (irq < 0) { |
458 | err = -EINVAL; | 458 | err = -EINVAL; |
459 | goto err_register; | 459 | goto err_register; |
460 | } | 460 | } |
461 | uart->port.irq = irq; | ||
461 | 462 | ||
462 | tasklet_init(&uart->tasklet, timbuart_tasklet, (unsigned long)uart); | 463 | tasklet_init(&uart->tasklet, timbuart_tasklet, (unsigned long)uart); |
463 | 464 | ||