aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2011-06-13 23:40:19 -0400
committerPaul Mundt <lethal@linux-sh.org>2011-06-13 23:40:19 -0400
commit61a6976bf19a6cf5dfcf37c3536665b316f22d49 (patch)
tree969831bb2a782454960a82a77d2802f62cc7ed91
parente13198894bf6308c097e5678ee315e12b2e1b7a8 (diff)
serial: sh-sci: Abstract register maps.
This takes a bit of a sledgehammer to the horribly CPU subtype ifdef-ridden header and abstracts all of the different register layouts in to distinct types which in turn can be overriden on a per-port basis, or permitted to default to the map matching the port type at probe time. In the process this ultimately fixes up inumerable bugs with mismatches on various CPU types (particularly the legacy ones that were obviously broken years ago and no one noticed) and provides a more tightly coupled and consolidated platform for extending and implementing generic features. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r--arch/sh/Makefile1
-rw-r--r--arch/sh/include/cpu-sh3/cpu/serial.h10
-rw-r--r--arch/sh/include/cpu-sh4a/cpu/serial.h7
-rw-r--r--arch/sh/kernel/cpu/sh3/Makefile18
-rw-r--r--arch/sh/kernel/cpu/sh3/serial-sh770x.c33
-rw-r--r--arch/sh/kernel/cpu/sh3/serial-sh7710.c20
-rw-r--r--arch/sh/kernel/cpu/sh3/serial-sh7720.c36
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7705.c5
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh770x.c8
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7720.c5
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7750.c3
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7760.c4
-rw-r--r--arch/sh/kernel/cpu/sh4a/Makefile2
-rw-r--r--arch/sh/kernel/cpu/sh4a/serial-sh7722.c23
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7366.c1
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7722.c6
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7723.c9
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7724.c9
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7763.c3
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7780.c3
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7785.c8
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7786.c8
-rw-r--r--drivers/tty/serial/sh-sci.c364
-rw-r--r--drivers/tty/serial/sh-sci.h222
-rw-r--r--include/linux/serial_sci.h36
25 files changed, 516 insertions, 328 deletions
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index e3d8170ad00..99385d0b3f3 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -173,6 +173,7 @@ core-$(CONFIG_HD6446X_SERIES) += arch/sh/cchips/hd6446x/
173cpuincdir-$(CONFIG_CPU_SH2A) += cpu-sh2a 173cpuincdir-$(CONFIG_CPU_SH2A) += cpu-sh2a
174cpuincdir-$(CONFIG_CPU_SH2) += cpu-sh2 174cpuincdir-$(CONFIG_CPU_SH2) += cpu-sh2
175cpuincdir-$(CONFIG_CPU_SH3) += cpu-sh3 175cpuincdir-$(CONFIG_CPU_SH3) += cpu-sh3
176cpuincdir-$(CONFIG_CPU_SH4A) += cpu-sh4a
176cpuincdir-$(CONFIG_CPU_SH4) += cpu-sh4 177cpuincdir-$(CONFIG_CPU_SH4) += cpu-sh4
177cpuincdir-$(CONFIG_CPU_SH5) += cpu-sh5 178cpuincdir-$(CONFIG_CPU_SH5) += cpu-sh5
178cpuincdir-y += cpu-common # Must be last 179cpuincdir-y += cpu-common # Must be last
diff --git a/arch/sh/include/cpu-sh3/cpu/serial.h b/arch/sh/include/cpu-sh3/cpu/serial.h
new file mode 100644
index 00000000000..7766329bc10
--- /dev/null
+++ b/arch/sh/include/cpu-sh3/cpu/serial.h
@@ -0,0 +1,10 @@
1#ifndef __CPU_SH3_SERIAL_H
2#define __CPU_SH3_SERIAL_H
3
4#include <linux/serial_sci.h>
5
6extern struct plat_sci_port_ops sh770x_sci_port_ops;
7extern struct plat_sci_port_ops sh7710_sci_port_ops;
8extern struct plat_sci_port_ops sh7720_sci_port_ops;
9
10#endif /* __CPU_SH3_SERIAL_H */
diff --git a/arch/sh/include/cpu-sh4a/cpu/serial.h b/arch/sh/include/cpu-sh4a/cpu/serial.h
new file mode 100644
index 00000000000..ff1bc275d21
--- /dev/null
+++ b/arch/sh/include/cpu-sh4a/cpu/serial.h
@@ -0,0 +1,7 @@
1#ifndef __CPU_SH4A_SERIAL_H
2#define __CPU_SH4A_SERIAL_H
3
4/* arch/sh/kernel/cpu/sh4a/serial-sh7722.c */
5extern struct plat_sci_port_ops sh7722_sci_port_ops;
6
7#endif /* __CPU_SH4A_SERIAL_H */
diff --git a/arch/sh/kernel/cpu/sh3/Makefile b/arch/sh/kernel/cpu/sh3/Makefile
index ecab274141a..6f13f33a35f 100644
--- a/arch/sh/kernel/cpu/sh3/Makefile
+++ b/arch/sh/kernel/cpu/sh3/Makefile
@@ -7,15 +7,15 @@ obj-y := ex.o probe.o entry.o setup-sh3.o
7obj-$(CONFIG_HIBERNATION) += swsusp.o 7obj-$(CONFIG_HIBERNATION) += swsusp.o
8 8
9# CPU subtype setup 9# CPU subtype setup
10obj-$(CONFIG_CPU_SUBTYPE_SH7705) += setup-sh7705.o 10obj-$(CONFIG_CPU_SUBTYPE_SH7705) += setup-sh7705.o serial-sh770x.o
11obj-$(CONFIG_CPU_SUBTYPE_SH7706) += setup-sh770x.o 11obj-$(CONFIG_CPU_SUBTYPE_SH7706) += setup-sh770x.o serial-sh770x.o
12obj-$(CONFIG_CPU_SUBTYPE_SH7707) += setup-sh770x.o 12obj-$(CONFIG_CPU_SUBTYPE_SH7707) += setup-sh770x.o serial-sh770x.o
13obj-$(CONFIG_CPU_SUBTYPE_SH7708) += setup-sh770x.o 13obj-$(CONFIG_CPU_SUBTYPE_SH7708) += setup-sh770x.o serial-sh770x.o
14obj-$(CONFIG_CPU_SUBTYPE_SH7709) += setup-sh770x.o 14obj-$(CONFIG_CPU_SUBTYPE_SH7709) += setup-sh770x.o serial-sh770x.o
15obj-$(CONFIG_CPU_SUBTYPE_SH7710) += setup-sh7710.o 15obj-$(CONFIG_CPU_SUBTYPE_SH7710) += setup-sh7710.o serial-sh7710.o
16obj-$(CONFIG_CPU_SUBTYPE_SH7712) += setup-sh7710.o 16obj-$(CONFIG_CPU_SUBTYPE_SH7712) += setup-sh7710.o serial-sh7710.o
17obj-$(CONFIG_CPU_SUBTYPE_SH7720) += setup-sh7720.o 17obj-$(CONFIG_CPU_SUBTYPE_SH7720) += setup-sh7720.o serial-sh7720.o
18obj-$(CONFIG_CPU_SUBTYPE_SH7721) += setup-sh7720.o 18obj-$(CONFIG_CPU_SUBTYPE_SH7721) += setup-sh7720.o serial-sh7720.o
19 19
20# Primary on-chip clocks (common) 20# Primary on-chip clocks (common)
21clock-$(CONFIG_CPU_SH3) := clock-sh3.o 21clock-$(CONFIG_CPU_SH3) := clock-sh3.o
diff --git a/arch/sh/kernel/cpu/sh3/serial-sh770x.c b/arch/sh/kernel/cpu/sh3/serial-sh770x.c
new file mode 100644
index 00000000000..4f7242c676b
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh3/serial-sh770x.c
@@ -0,0 +1,33 @@
1#include <linux/serial_sci.h>
2#include <linux/serial_core.h>
3#include <linux/io.h>
4#include <cpu/serial.h>
5
6#define SCPCR 0xA4000116
7#define SCPDR 0xA4000136
8
9static void sh770x_sci_init_pins(struct uart_port *port, unsigned int cflag)
10{
11 unsigned short data;
12
13 /* We need to set SCPCR to enable RTS/CTS */
14 data = __raw_readw(SCPCR);
15 /* Clear out SCP7MD1,0, SCP6MD1,0, SCP4MD1,0*/
16 __raw_writew(data & 0x0fcf, SCPCR);
17
18 if (!(cflag & CRTSCTS)) {
19 /* We need to set SCPCR to enable RTS/CTS */
20 data = __raw_readw(SCPCR);
21 /* Clear out SCP7MD1,0, SCP4MD1,0,
22 Set SCP6MD1,0 = {01} (output) */
23 __raw_writew((data & 0x0fcf) | 0x1000, SCPCR);
24
25 data = __raw_readb(SCPDR);
26 /* Set /RTS2 (bit6) = 0 */
27 __raw_writeb(data & 0xbf, SCPDR);
28 }
29}
30
31struct plat_sci_port_ops sh770x_sci_port_ops = {
32 .init_pins = sh770x_sci_init_pins,
33};
diff --git a/arch/sh/kernel/cpu/sh3/serial-sh7710.c b/arch/sh/kernel/cpu/sh3/serial-sh7710.c
new file mode 100644
index 00000000000..42190ef6aeb
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh3/serial-sh7710.c
@@ -0,0 +1,20 @@
1#include <linux/serial_sci.h>
2#include <linux/serial_core.h>
3#include <linux/io.h>
4#include <cpu/serial.h>
5
6#define PACR 0xa4050100
7#define PBCR 0xa4050102
8
9static void sh7710_sci_init_pins(struct uart_port *port, unsigned int cflag)
10{
11 if (port->mapbase == 0xA4400000) {
12 __raw_writew(__raw_readw(PACR) & 0xffc0, PACR);
13 __raw_writew(__raw_readw(PBCR) & 0x0fff, PBCR);
14 } else if (port->mapbase == 0xA4410000)
15 __raw_writew(__raw_readw(PBCR) & 0xf003, PBCR);
16}
17
18struct plat_sci_port_ops sh7710_sci_port_ops = {
19 .init_pins = sh7710_sci_init_pins,
20};
diff --git a/arch/sh/kernel/cpu/sh3/serial-sh7720.c b/arch/sh/kernel/cpu/sh3/serial-sh7720.c
new file mode 100644
index 00000000000..8234e1e7abd
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh3/serial-sh7720.c
@@ -0,0 +1,36 @@
1#include <linux/serial_sci.h>
2#include <linux/serial_core.h>
3#include <linux/io.h>
4#include <cpu/serial.h>
5
6static void sh7720_sci_init_pins(struct uart_port *port, unsigned int cflag)
7{
8 unsigned short data;
9
10 if (cflag & CRTSCTS) {
11 /* enable RTS/CTS */
12 if (port->mapbase == 0xa4430000) { /* SCIF0 */
13 /* Clear PTCR bit 9-2; enable all scif pins but sck */
14 data = __raw_readw(PORT_PTCR);
15 __raw_writew((data & 0xfc03), PORT_PTCR);
16 } else if (port->mapbase == 0xa4438000) { /* SCIF1 */
17 /* Clear PVCR bit 9-2 */
18 data = __raw_readw(PORT_PVCR);
19 __raw_writew((data & 0xfc03), PORT_PVCR);
20 }
21 } else {
22 if (port->mapbase == 0xa4430000) { /* SCIF0 */
23 /* Clear PTCR bit 5-2; enable only tx and rx */
24 data = __raw_readw(PORT_PTCR);
25 __raw_writew((data & 0xffc3), PORT_PTCR);
26 } else if (port->mapbase == 0xa4438000) { /* SCIF1 */
27 /* Clear PVCR bit 5-2 */
28 data = __raw_readw(PORT_PVCR);
29 __raw_writew((data & 0xffc3), PORT_PVCR);
30 }
31 }
32}
33
34struct plat_sci_port_ops sh7720_sci_port_ops = {
35 .init_pins = sh7720_sci_init_pins,
36};
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
index cd2e702feb7..2309618c015 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
@@ -15,6 +15,7 @@
15#include <linux/serial_sci.h> 15#include <linux/serial_sci.h>
16#include <linux/sh_timer.h> 16#include <linux/sh_timer.h>
17#include <asm/rtc.h> 17#include <asm/rtc.h>
18#include <cpu/serial.h>
18 19
19enum { 20enum {
20 UNUSED = 0, 21 UNUSED = 0,
@@ -75,6 +76,8 @@ static struct plat_sci_port scif0_platform_data = {
75 .scbrr_algo_id = SCBRR_ALGO_4, 76 .scbrr_algo_id = SCBRR_ALGO_4,
76 .type = PORT_SCIF, 77 .type = PORT_SCIF,
77 .irqs = { 56, 56, 56 }, 78 .irqs = { 56, 56, 56 },
79 .ops = &sh770x_sci_port_ops,
80 .regtype = SCIx_SH7705_SCIF_REGTYPE,
78}; 81};
79 82
80static struct platform_device scif0_device = { 83static struct platform_device scif0_device = {
@@ -92,6 +95,8 @@ static struct plat_sci_port scif1_platform_data = {
92 .scbrr_algo_id = SCBRR_ALGO_4, 95 .scbrr_algo_id = SCBRR_ALGO_4,
93 .type = PORT_SCIF, 96 .type = PORT_SCIF,
94 .irqs = { 52, 52, 52 }, 97 .irqs = { 52, 52, 52 },
98 .ops = &sh770x_sci_port_ops,
99 .regtype = SCIx_SH7705_SCIF_REGTYPE,
95}; 100};
96 101
97static struct platform_device scif1_device = { 102static struct platform_device scif1_device = {
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c
index 6d549792f79..3f3d5fe5892 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c
@@ -19,6 +19,7 @@
19#include <linux/serial.h> 19#include <linux/serial.h>
20#include <linux/serial_sci.h> 20#include <linux/serial_sci.h>
21#include <linux/sh_timer.h> 21#include <linux/sh_timer.h>
22#include <cpu/serial.h>
22 23
23enum { 24enum {
24 UNUSED = 0, 25 UNUSED = 0,
@@ -114,6 +115,8 @@ static struct plat_sci_port scif0_platform_data = {
114 .scbrr_algo_id = SCBRR_ALGO_2, 115 .scbrr_algo_id = SCBRR_ALGO_2,
115 .type = PORT_SCI, 116 .type = PORT_SCI,
116 .irqs = { 23, 23, 23, 0 }, 117 .irqs = { 23, 23, 23, 0 },
118 .ops = &sh770x_sci_port_ops,
119 .regshift = 1,
117}; 120};
118 121
119static struct platform_device scif0_device = { 122static struct platform_device scif0_device = {
@@ -133,6 +136,8 @@ static struct plat_sci_port scif1_platform_data = {
133 .scbrr_algo_id = SCBRR_ALGO_2, 136 .scbrr_algo_id = SCBRR_ALGO_2,
134 .type = PORT_SCIF, 137 .type = PORT_SCIF,
135 .irqs = { 56, 56, 56, 56 }, 138 .irqs = { 56, 56, 56, 56 },
139 .ops = &sh770x_sci_port_ops,
140 .regtype = SCIx_SH3_SCIF_REGTYPE,
136}; 141};
137 142
138static struct platform_device scif1_device = { 143static struct platform_device scif1_device = {
@@ -147,11 +152,14 @@ static struct platform_device scif1_device = {
147 defined(CONFIG_CPU_SUBTYPE_SH7709) 152 defined(CONFIG_CPU_SUBTYPE_SH7709)
148static struct plat_sci_port scif2_platform_data = { 153static struct plat_sci_port scif2_platform_data = {
149 .mapbase = 0xa4000140, 154 .mapbase = 0xa4000140,
155 .port_reg = SCIx_NOT_SUPPORTED,
150 .flags = UPF_BOOT_AUTOCONF, 156 .flags = UPF_BOOT_AUTOCONF,
151 .scscr = SCSCR_TE | SCSCR_RE, 157 .scscr = SCSCR_TE | SCSCR_RE,
152 .scbrr_algo_id = SCBRR_ALGO_2, 158 .scbrr_algo_id = SCBRR_ALGO_2,
153 .type = PORT_IRDA, 159 .type = PORT_IRDA,
154 .irqs = { 52, 52, 52, 52 }, 160 .irqs = { 52, 52, 52, 52 },
161 .ops = &sh770x_sci_port_ops,
162 .regshift = 1,
155}; 163};
156 164
157static struct platform_device scif2_device = { 165static struct platform_device scif2_device = {
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c
index 365b94a6fcb..94920345c14 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c
@@ -20,6 +20,7 @@
20#include <linux/serial_sci.h> 20#include <linux/serial_sci.h>
21#include <linux/sh_timer.h> 21#include <linux/sh_timer.h>
22#include <asm/rtc.h> 22#include <asm/rtc.h>
23#include <cpu/serial.h>
23 24
24static struct resource rtc_resources[] = { 25static struct resource rtc_resources[] = {
25 [0] = { 26 [0] = {
@@ -55,6 +56,8 @@ static struct plat_sci_port scif0_platform_data = {
55 .scbrr_algo_id = SCBRR_ALGO_4, 56 .scbrr_algo_id = SCBRR_ALGO_4,
56 .type = PORT_SCIF, 57 .type = PORT_SCIF,
57 .irqs = { 80, 80, 80, 80 }, 58 .irqs = { 80, 80, 80, 80 },
59 .ops = &sh7720_sci_port_ops,
60 .regtype = SCIx_SH7705_SCIF_REGTYPE,
58}; 61};
59 62
60static struct platform_device scif0_device = { 63static struct platform_device scif0_device = {
@@ -72,6 +75,8 @@ static struct plat_sci_port scif1_platform_data = {
72 .scbrr_algo_id = SCBRR_ALGO_4, 75 .scbrr_algo_id = SCBRR_ALGO_4,
73 .type = PORT_SCIF, 76 .type = PORT_SCIF,
74 .irqs = { 81, 81, 81, 81 }, 77 .irqs = { 81, 81, 81, 81 },
78 .ops = &sh7720_sci_port_ops,
79 .regtype = SCIx_SH7705_SCIF_REGTYPE,
75}; 80};
76 81
77static struct platform_device scif1_device = { 82static struct platform_device scif1_device = {
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
index 8ea26e79118..c10db5b96e5 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * SH7750/SH7751 Setup 2 * SH7091/SH7750/SH7750S/SH7750R/SH7751/SH7751R Setup
3 * 3 *
4 * Copyright (C) 2006 Paul Mundt 4 * Copyright (C) 2006 Paul Mundt
5 * Copyright (C) 2006 Jamie Lenehan 5 * Copyright (C) 2006 Jamie Lenehan
@@ -44,6 +44,7 @@ static struct plat_sci_port sci_platform_data = {
44 .scbrr_algo_id = SCBRR_ALGO_2, 44 .scbrr_algo_id = SCBRR_ALGO_2,
45 .type = PORT_SCI, 45 .type = PORT_SCI,
46 .irqs = { 23, 23, 23, 0 }, 46 .irqs = { 23, 23, 23, 0 },
47 .regshift = 2,
47}; 48};
48 49
49static struct platform_device sci_device = { 50static struct platform_device sci_device = {
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c
index 78bbf232e39..c0b4c774700 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c
@@ -133,6 +133,7 @@ static struct plat_sci_port scif0_platform_data = {
133 .scbrr_algo_id = SCBRR_ALGO_2, 133 .scbrr_algo_id = SCBRR_ALGO_2,
134 .type = PORT_SCIF, 134 .type = PORT_SCIF,
135 .irqs = { 52, 53, 55, 54 }, 135 .irqs = { 52, 53, 55, 54 },
136 .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
136}; 137};
137 138
138static struct platform_device scif0_device = { 139static struct platform_device scif0_device = {
@@ -150,6 +151,7 @@ static struct plat_sci_port scif1_platform_data = {
150 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, 151 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
151 .scbrr_algo_id = SCBRR_ALGO_2, 152 .scbrr_algo_id = SCBRR_ALGO_2,
152 .irqs = { 72, 73, 75, 74 }, 153 .irqs = { 72, 73, 75, 74 },
154 .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
153}; 155};
154 156
155static struct platform_device scif1_device = { 157static struct platform_device scif1_device = {
@@ -167,6 +169,7 @@ static struct plat_sci_port scif2_platform_data = {
167 .scbrr_algo_id = SCBRR_ALGO_2, 169 .scbrr_algo_id = SCBRR_ALGO_2,
168 .type = PORT_SCIF, 170 .type = PORT_SCIF,
169 .irqs = { 76, 77, 79, 78 }, 171 .irqs = { 76, 77, 79, 78 },
172 .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
170}; 173};
171 174
172static struct platform_device scif2_device = { 175static struct platform_device scif2_device = {
@@ -184,6 +187,7 @@ static struct plat_sci_port scif3_platform_data = {
184 .scbrr_algo_id = SCBRR_ALGO_2, 187 .scbrr_algo_id = SCBRR_ALGO_2,
185 .type = PORT_SCI, 188 .type = PORT_SCI,
186 .irqs = { 80, 81, 82, 0 }, 189 .irqs = { 80, 81, 82, 0 },
190 .regshift = 2,
187}; 191};
188 192
189static struct platform_device scif3_device = { 193static struct platform_device scif3_device = {
diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile
index cc122b1d303..c57fb287011 100644
--- a/arch/sh/kernel/cpu/sh4a/Makefile
+++ b/arch/sh/kernel/cpu/sh4a/Makefile
@@ -10,7 +10,7 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7780) += setup-sh7780.o
10obj-$(CONFIG_CPU_SUBTYPE_SH7785) += setup-sh7785.o 10obj-$(CONFIG_CPU_SUBTYPE_SH7785) += setup-sh7785.o
11obj-$(CONFIG_CPU_SUBTYPE_SH7786) += setup-sh7786.o intc-shx3.o 11obj-$(CONFIG_CPU_SUBTYPE_SH7786) += setup-sh7786.o intc-shx3.o
12obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o 12obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o
13obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o 13obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o serial-sh7722.o
14obj-$(CONFIG_CPU_SUBTYPE_SH7723) += setup-sh7723.o 14obj-$(CONFIG_CPU_SUBTYPE_SH7723) += setup-sh7723.o
15obj-$(CONFIG_CPU_SUBTYPE_SH7724) += setup-sh7724.o 15obj-$(CONFIG_CPU_SUBTYPE_SH7724) += setup-sh7724.o
16obj-$(CONFIG_CPU_SUBTYPE_SH7366) += setup-sh7366.o 16obj-$(CONFIG_CPU_SUBTYPE_SH7366) += setup-sh7366.o
diff --git a/arch/sh/kernel/cpu/sh4a/serial-sh7722.c b/arch/sh/kernel/cpu/sh4a/serial-sh7722.c
new file mode 100644
index 00000000000..59bc3a72702
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/serial-sh7722.c
@@ -0,0 +1,23 @@
1#include <linux/serial_sci.h>
2#include <linux/serial_core.h>
3#include <linux/io.h>
4
5#define PSCR 0xA405011E
6
7static void sh7722_sci_init_pins(struct uart_port *port, unsigned int cflag)
8{
9 unsigned short data;
10
11 if (port->mapbase == 0xffe00000) {
12 data = __raw_readw(PSCR);
13 data &= ~0x03cf;
14 if (!(cflag & CRTSCTS))
15 data |= 0x0340;
16
17 __raw_writew(data, PSCR);
18 }
19}
20
21struct plat_sci_port_ops sh7722_sci_port_ops = {
22 .init_pins = sh7722_sci_init_pins,
23};
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
index 82616af64d6..87773869a2f 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
@@ -20,6 +20,7 @@
20 20
21static struct plat_sci_port scif0_platform_data = { 21static struct plat_sci_port scif0_platform_data = {
22 .mapbase = 0xffe00000, 22 .mapbase = 0xffe00000,
23 .port_reg = 0xa405013e,
23 .flags = UPF_BOOT_AUTOCONF, 24 .flags = UPF_BOOT_AUTOCONF,
24 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, 25 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
25 .scbrr_algo_id = SCBRR_ALGO_2, 26 .scbrr_algo_id = SCBRR_ALGO_2,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
index 5813d802361..863249dbf05 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
@@ -185,6 +185,8 @@ static struct plat_sci_port scif0_platform_data = {
185 .scbrr_algo_id = SCBRR_ALGO_2, 185 .scbrr_algo_id = SCBRR_ALGO_2,
186 .type = PORT_SCIF, 186 .type = PORT_SCIF,
187 .irqs = { 80, 80, 80, 80 }, 187 .irqs = { 80, 80, 80, 80 },
188 .ops = &sh7722_sci_port_ops,
189 .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
188}; 190};
189 191
190static struct platform_device scif0_device = { 192static struct platform_device scif0_device = {
@@ -202,6 +204,8 @@ static struct plat_sci_port scif1_platform_data = {
202 .scbrr_algo_id = SCBRR_ALGO_2, 204 .scbrr_algo_id = SCBRR_ALGO_2,
203 .type = PORT_SCIF, 205 .type = PORT_SCIF,
204 .irqs = { 81, 81, 81, 81 }, 206 .irqs = { 81, 81, 81, 81 },
207 .ops = &sh7722_sci_port_ops,
208 .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
205}; 209};
206 210
207static struct platform_device scif1_device = { 211static struct platform_device scif1_device = {
@@ -219,6 +223,8 @@ static struct plat_sci_port scif2_platform_data = {
219 .scbrr_algo_id = SCBRR_ALGO_2, 223 .scbrr_algo_id = SCBRR_ALGO_2,
220 .type = PORT_SCIF, 224 .type = PORT_SCIF,
221 .irqs = { 82, 82, 82, 82 }, 225 .irqs = { 82, 82, 82, 82 },
226 .ops = &sh7722_sci_port_ops,
227 .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
222}; 228};
223 229
224static struct platform_device scif2_device = { 230static struct platform_device scif2_device = {
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
index 072382280f9..3c2810d8f72 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
@@ -23,11 +23,13 @@
23/* Serial */ 23/* Serial */
24static struct plat_sci_port scif0_platform_data = { 24static struct plat_sci_port scif0_platform_data = {
25 .mapbase = 0xffe00000, 25 .mapbase = 0xffe00000,
26 .port_reg = 0xa4050160,
26 .flags = UPF_BOOT_AUTOCONF, 27 .flags = UPF_BOOT_AUTOCONF,
27 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, 28 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
28 .scbrr_algo_id = SCBRR_ALGO_2, 29 .scbrr_algo_id = SCBRR_ALGO_2,
29 .type = PORT_SCIF, 30 .type = PORT_SCIF,
30 .irqs = { 80, 80, 80, 80 }, 31 .irqs = { 80, 80, 80, 80 },
32 .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
31}; 33};
32 34
33static struct platform_device scif0_device = { 35static struct platform_device scif0_device = {
@@ -40,11 +42,13 @@ static struct platform_device scif0_device = {
40 42
41static struct plat_sci_port scif1_platform_data = { 43static struct plat_sci_port scif1_platform_data = {
42 .mapbase = 0xffe10000, 44 .mapbase = 0xffe10000,
45 .port_reg = SCIx_NOT_SUPPORTED,
43 .flags = UPF_BOOT_AUTOCONF, 46 .flags = UPF_BOOT_AUTOCONF,
44 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, 47 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
45 .scbrr_algo_id = SCBRR_ALGO_2, 48 .scbrr_algo_id = SCBRR_ALGO_2,
46 .type = PORT_SCIF, 49 .type = PORT_SCIF,
47 .irqs = { 81, 81, 81, 81 }, 50 .irqs = { 81, 81, 81, 81 },
51 .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
48}; 52};
49 53
50static struct platform_device scif1_device = { 54static struct platform_device scif1_device = {
@@ -57,11 +61,13 @@ static struct platform_device scif1_device = {
57 61
58static struct plat_sci_port scif2_platform_data = { 62static struct plat_sci_port scif2_platform_data = {
59 .mapbase = 0xffe20000, 63 .mapbase = 0xffe20000,
64 .port_reg = SCIx_NOT_SUPPORTED,
60 .flags = UPF_BOOT_AUTOCONF, 65 .flags = UPF_BOOT_AUTOCONF,
61 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, 66 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
62 .scbrr_algo_id = SCBRR_ALGO_2, 67 .scbrr_algo_id = SCBRR_ALGO_2,
63 .type = PORT_SCIF, 68 .type = PORT_SCIF,
64 .irqs = { 82, 82, 82, 82 }, 69 .irqs = { 82, 82, 82, 82 },
70 .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
65}; 71};
66 72
67static struct platform_device scif2_device = { 73static struct platform_device scif2_device = {
@@ -75,6 +81,7 @@ static struct platform_device scif2_device = {
75static struct plat_sci_port scif3_platform_data = { 81static struct plat_sci_port scif3_platform_data = {
76 .mapbase = 0xa4e30000, 82 .mapbase = 0xa4e30000,
77 .flags = UPF_BOOT_AUTOCONF, 83 .flags = UPF_BOOT_AUTOCONF,
84 .port_reg = SCIx_NOT_SUPPORTED,
78 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, 85 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
79 .scbrr_algo_id = SCBRR_ALGO_3, 86 .scbrr_algo_id = SCBRR_ALGO_3,
80 .type = PORT_SCIFA, 87 .type = PORT_SCIFA,
@@ -91,6 +98,7 @@ static struct platform_device scif3_device = {
91 98
92static struct plat_sci_port scif4_platform_data = { 99static struct plat_sci_port scif4_platform_data = {
93 .mapbase = 0xa4e40000, 100 .mapbase = 0xa4e40000,
101 .port_reg = SCIx_NOT_SUPPORTED,
94 .flags = UPF_BOOT_AUTOCONF, 102 .flags = UPF_BOOT_AUTOCONF,
95 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, 103 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
96 .scbrr_algo_id = SCBRR_ALGO_3, 104 .scbrr_algo_id = SCBRR_ALGO_3,
@@ -108,6 +116,7 @@ static struct platform_device scif4_device = {
108 116
109static struct plat_sci_port scif5_platform_data = { 117static struct plat_sci_port scif5_platform_data = {
110 .mapbase = 0xa4e50000, 118 .mapbase = 0xa4e50000,
119 .port_reg = SCIx_NOT_SUPPORTED,
111 .flags = UPF_BOOT_AUTOCONF, 120 .flags = UPF_BOOT_AUTOCONF,
112 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, 121 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
113 .scbrr_algo_id = SCBRR_ALGO_3, 122 .scbrr_algo_id = SCBRR_ALGO_3,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
index 0333fe9e388..8c892887ebd 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
@@ -256,11 +256,13 @@ static struct platform_device dma1_device = {
256/* Serial */ 256/* Serial */
257static struct plat_sci_port scif0_platform_data = { 257static struct plat_sci_port scif0_platform_data = {
258 .mapbase = 0xffe00000, 258 .mapbase = 0xffe00000,
259 .port_reg = SCIx_NOT_SUPPORTED,
259 .flags = UPF_BOOT_AUTOCONF, 260 .flags = UPF_BOOT_AUTOCONF,
260 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, 261 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
261 .scbrr_algo_id = SCBRR_ALGO_2, 262 .scbrr_algo_id = SCBRR_ALGO_2,
262 .type = PORT_SCIF, 263 .type = PORT_SCIF,
263 .irqs = { 80, 80, 80, 80 }, 264 .irqs = { 80, 80, 80, 80 },
265 .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
264}; 266};
265 267
266static struct platform_device scif0_device = { 268static struct platform_device scif0_device = {
@@ -273,11 +275,13 @@ static struct platform_device scif0_device = {
273 275
274static struct plat_sci_port scif1_platform_data = { 276static struct plat_sci_port scif1_platform_data = {
275 .mapbase = 0xffe10000, 277 .mapbase = 0xffe10000,
278 .port_reg = SCIx_NOT_SUPPORTED,
276 .flags = UPF_BOOT_AUTOCONF, 279 .flags = UPF_BOOT_AUTOCONF,
277 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, 280 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
278 .scbrr_algo_id = SCBRR_ALGO_2, 281 .scbrr_algo_id = SCBRR_ALGO_2,
279 .type = PORT_SCIF, 282 .type = PORT_SCIF,
280 .irqs = { 81, 81, 81, 81 }, 283 .irqs = { 81, 81, 81, 81 },
284 .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
281}; 285};
282 286
283static struct platform_device scif1_device = { 287static struct platform_device scif1_device = {
@@ -290,11 +294,13 @@ static struct platform_device scif1_device = {
290 294
291static struct plat_sci_port scif2_platform_data = { 295static struct plat_sci_port scif2_platform_data = {
292 .mapbase = 0xffe20000, 296 .mapbase = 0xffe20000,
297 .port_reg = SCIx_NOT_SUPPORTED,
293 .flags = UPF_BOOT_AUTOCONF, 298 .flags = UPF_BOOT_AUTOCONF,
294 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, 299 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
295 .scbrr_algo_id = SCBRR_ALGO_2, 300 .scbrr_algo_id = SCBRR_ALGO_2,
296 .type = PORT_SCIF, 301 .type = PORT_SCIF,
297 .irqs = { 82, 82, 82, 82 }, 302 .irqs = { 82, 82, 82, 82 },
303 .regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
298}; 304};
299 305
300static struct platform_device scif2_device = { 306static struct platform_device scif2_device = {
@@ -307,6 +313,7 @@ static struct platform_device scif2_device = {
307 313
308static struct plat_sci_port scif3_platform_data = { 314static struct plat_sci_port scif3_platform_data = {
309 .mapbase = 0xa4e30000, 315 .mapbase = 0xa4e30000,
316 .port_reg = SCIx_NOT_SUPPORTED,
310 .flags = UPF_BOOT_AUTOCONF, 317 .flags = UPF_BOOT_AUTOCONF,
311 .scscr = SCSCR_RE | SCSCR_TE, 318 .scscr = SCSCR_RE | SCSCR_TE,
312 .scbrr_algo_id = SCBRR_ALGO_3, 319 .scbrr_algo_id = SCBRR_ALGO_3,
@@ -324,6 +331,7 @@ static struct platform_device scif3_device = {
324 331
325static struct plat_sci_port scif4_platform_data = { 332static struct plat_sci_port scif4_platform_data = {
326 .mapbase = 0xa4e40000, 333 .mapbase = 0xa4e40000,
334 .port_reg = SCIx_NOT_SUPPORTED,
327 .flags = UPF_BOOT_AUTOCONF, 335 .flags = UPF_BOOT_AUTOCONF,
328 .scscr = SCSCR_RE | SCSCR_TE, 336 .scscr = SCSCR_RE | SCSCR_TE,
329 .scbrr_algo_id = SCBRR_ALGO_3, 337 .scbrr_algo_id = SCBRR_ALGO_3,
@@ -341,6 +349,7 @@ static struct platform_device scif4_device = {
341 349
342static struct plat_sci_port scif5_platform_data = { 350static struct plat_sci_port scif5_platform_data = {
343 .mapbase = 0xa4e50000, 351 .mapbase = 0xa4e50000,
352 .port_reg = SCIx_NOT_SUPPORTED,
344 .flags = UPF_BOOT_AUTOCONF, 353 .flags = UPF_BOOT_AUTOCONF,
345 .scscr = SCSCR_RE | SCSCR_TE, 354 .scscr = SCSCR_RE | SCSCR_TE,
346 .scbrr_algo_id = SCBRR_ALGO_3, 355 .scbrr_algo_id = SCBRR_ALGO_3,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
index 593eca6509b..00113515f23 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
@@ -23,6 +23,7 @@ static struct plat_sci_port scif0_platform_data = {
23 .scbrr_algo_id = SCBRR_ALGO_2, 23 .scbrr_algo_id = SCBRR_ALGO_2,
24 .type = PORT_SCIF, 24 .type = PORT_SCIF,
25 .irqs = { 40, 40, 40, 40 }, 25 .irqs = { 40, 40, 40, 40 },
26 .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
26}; 27};
27 28
28static struct platform_device scif0_device = { 29static struct platform_device scif0_device = {
@@ -40,6 +41,7 @@ static struct plat_sci_port scif1_platform_data = {
40 .scbrr_algo_id = SCBRR_ALGO_2, 41 .scbrr_algo_id = SCBRR_ALGO_2,
41 .type = PORT_SCIF, 42 .type = PORT_SCIF,
42 .irqs = { 76, 76, 76, 76 }, 43 .irqs = { 76, 76, 76, 76 },
44 .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
43}; 45};
44 46
45static struct platform_device scif1_device = { 47static struct platform_device scif1_device = {
@@ -57,6 +59,7 @@ static struct plat_sci_port scif2_platform_data = {
57 .scbrr_algo_id = SCBRR_ALGO_2, 59 .scbrr_algo_id = SCBRR_ALGO_2,
58 .type = PORT_SCIF, 60 .type = PORT_SCIF,
59 .irqs = { 104, 104, 104, 104 }, 61 .irqs = { 104, 104, 104, 104 },
62 .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
60}; 63};
61 64
62static struct platform_device scif2_device = { 65static struct platform_device scif2_device = {
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
index 08add7fa684..3d4d2075c19 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
@@ -14,7 +14,6 @@
14#include <linux/serial_sci.h> 14#include <linux/serial_sci.h>
15#include <linux/sh_dma.h> 15#include <linux/sh_dma.h>
16#include <linux/sh_timer.h> 16#include <linux/sh_timer.h>
17
18#include <cpu/dma-register.h> 17#include <cpu/dma-register.h>
19 18
20static struct plat_sci_port scif0_platform_data = { 19static struct plat_sci_port scif0_platform_data = {
@@ -24,6 +23,7 @@ static struct plat_sci_port scif0_platform_data = {
24 .scbrr_algo_id = SCBRR_ALGO_1, 23 .scbrr_algo_id = SCBRR_ALGO_1,
25 .type = PORT_SCIF, 24 .type = PORT_SCIF,
26 .irqs = { 40, 40, 40, 40 }, 25 .irqs = { 40, 40, 40, 40 },
26 .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
27}; 27};
28 28
29static struct platform_device scif0_device = { 29static struct platform_device scif0_device = {
@@ -41,6 +41,7 @@ static struct plat_sci_port scif1_platform_data = {
41 .scbrr_algo_id = SCBRR_ALGO_1, 41 .scbrr_algo_id = SCBRR_ALGO_1,
42 .type = PORT_SCIF, 42 .type = PORT_SCIF,
43 .irqs = { 76, 76, 76, 76 }, 43 .irqs = { 76, 76, 76, 76 },
44 .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
44}; 45};
45 46
46static struct platform_device scif1_device = { 47static struct platform_device scif1_device = {
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
index 18d8fc136fb..b29e6340414 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
@@ -15,9 +15,7 @@
15#include <linux/mm.h> 15#include <linux/mm.h>
16#include <linux/sh_dma.h> 16#include <linux/sh_dma.h>
17#include <linux/sh_timer.h> 17#include <linux/sh_timer.h>
18
19#include <asm/mmzone.h> 18#include <asm/mmzone.h>
20
21#include <cpu/dma-register.h> 19#include <cpu/dma-register.h>
22 20
23static struct plat_sci_port scif0_platform_data = { 21static struct plat_sci_port scif0_platform_data = {
@@ -27,6 +25,7 @@ static struct plat_sci_port scif0_platform_data = {
27 .scbrr_algo_id = SCBRR_ALGO_1, 25 .scbrr_algo_id = SCBRR_ALGO_1,
28 .type = PORT_SCIF, 26 .type = PORT_SCIF,
29 .irqs = { 40, 40, 40, 40 }, 27 .irqs = { 40, 40, 40, 40 },
28 .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
30}; 29};
31 30
32static struct platform_device scif0_device = { 31static struct platform_device scif0_device = {
@@ -44,6 +43,7 @@ static struct plat_sci_port scif1_platform_data = {
44 .scbrr_algo_id = SCBRR_ALGO_1, 43 .scbrr_algo_id = SCBRR_ALGO_1,
45 .type = PORT_SCIF, 44 .type = PORT_SCIF,
46 .irqs = { 44, 44, 44, 44 }, 45 .irqs = { 44, 44, 44, 44 },
46 .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
47}; 47};
48 48
49static struct platform_device scif1_device = { 49static struct platform_device scif1_device = {
@@ -61,6 +61,7 @@ static struct plat_sci_port scif2_platform_data = {
61 .scbrr_algo_id = SCBRR_ALGO_1, 61 .scbrr_algo_id = SCBRR_ALGO_1,
62 .type = PORT_SCIF, 62 .type = PORT_SCIF,
63 .irqs = { 60, 60, 60, 60 }, 63 .irqs = { 60, 60, 60, 60 },
64 .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
64}; 65};
65 66
66static struct platform_device scif2_device = { 67static struct platform_device scif2_device = {
@@ -78,6 +79,7 @@ static struct plat_sci_port scif3_platform_data = {
78 .scbrr_algo_id = SCBRR_ALGO_1, 79 .scbrr_algo_id = SCBRR_ALGO_1,
79 .type = PORT_SCIF, 80 .type = PORT_SCIF,
80 .irqs = { 61, 61, 61, 61 }, 81 .irqs = { 61, 61, 61, 61 },
82 .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
81}; 83};
82 84
83static struct platform_device scif3_device = { 85static struct platform_device scif3_device = {
@@ -95,6 +97,7 @@ static struct plat_sci_port scif4_platform_data = {
95 .scbrr_algo_id = SCBRR_ALGO_1, 97 .scbrr_algo_id = SCBRR_ALGO_1,
96 .type = PORT_SCIF, 98 .type = PORT_SCIF,
97 .irqs = { 62, 62, 62, 62 }, 99 .irqs = { 62, 62, 62, 62 },
100 .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
98}; 101};
99 102
100static struct platform_device scif4_device = { 103static struct platform_device scif4_device = {
@@ -112,6 +115,7 @@ static struct plat_sci_port scif5_platform_data = {
112 .scbrr_algo_id = SCBRR_ALGO_1, 115 .scbrr_algo_id = SCBRR_ALGO_1,
113 .type = PORT_SCIF, 116 .type = PORT_SCIF,
114 .irqs = { 63, 63, 63, 63 }, 117 .irqs = { 63, 63, 63, 63 },
118 .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
115}; 119};
116 120
117static struct platform_device scif5_device = { 121static struct platform_device scif5_device = {
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
index beba32beb6d..dd5e709f982 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * SH7786 Setup 2 * SH7786 Setup
3 * 3 *
4 * Copyright (C) 2009 - 2010 Renesas Solutions Corp. 4 * Copyright (C) 2009 - 2011 Renesas Solutions Corp.
5 * Kuninori Morimoto <morimoto.kuninori@renesas.com> 5 * Kuninori Morimoto <morimoto.kuninori@renesas.com>
6 * Paul Mundt <paul.mundt@renesas.com> 6 * Paul Mundt <paul.mundt@renesas.com>
7 * 7 *
@@ -33,6 +33,7 @@ static struct plat_sci_port scif0_platform_data = {
33 .scbrr_algo_id = SCBRR_ALGO_1, 33 .scbrr_algo_id = SCBRR_ALGO_1,
34 .type = PORT_SCIF, 34 .type = PORT_SCIF,
35 .irqs = { 40, 41, 43, 42 }, 35 .irqs = { 40, 41, 43, 42 },
36 .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
36}; 37};
37 38
38static struct platform_device scif0_device = { 39static struct platform_device scif0_device = {
@@ -53,6 +54,7 @@ static struct plat_sci_port scif1_platform_data = {
53 .scbrr_algo_id = SCBRR_ALGO_1, 54 .scbrr_algo_id = SCBRR_ALGO_1,
54 .type = PORT_SCIF, 55 .type = PORT_SCIF,
55 .irqs = { 44, 44, 44, 44 }, 56 .irqs = { 44, 44, 44, 44 },
57 .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
56}; 58};
57 59
58static struct platform_device scif1_device = { 60static struct platform_device scif1_device = {
@@ -70,6 +72,7 @@ static struct plat_sci_port scif2_platform_data = {
70 .scbrr_algo_id = SCBRR_ALGO_1, 72 .scbrr_algo_id = SCBRR_ALGO_1,
71 .type = PORT_SCIF, 73 .type = PORT_SCIF,
72 .irqs = { 50, 50, 50, 50 }, 74 .irqs = { 50, 50, 50, 50 },
75 .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
73}; 76};
74 77
75static struct platform_device scif2_device = { 78static struct platform_device scif2_device = {
@@ -87,6 +90,7 @@ static struct plat_sci_port scif3_platform_data = {
87 .scbrr_algo_id = SCBRR_ALGO_1, 90 .scbrr_algo_id = SCBRR_ALGO_1,
88 .type = PORT_SCIF, 91 .type = PORT_SCIF,
89 .irqs = { 51, 51, 51, 51 }, 92 .irqs = { 51, 51, 51, 51 },
93 .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
90}; 94};
91 95
92static struct platform_device scif3_device = { 96static struct platform_device scif3_device = {
@@ -104,6 +108,7 @@ static struct plat_sci_port scif4_platform_data = {
104 .scbrr_algo_id = SCBRR_ALGO_1, 108 .scbrr_algo_id = SCBRR_ALGO_1,
105 .type = PORT_SCIF, 109 .type = PORT_SCIF,
106 .irqs = { 52, 52, 52, 52 }, 110 .irqs = { 52, 52, 52, 52 },
111 .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
107}; 112};
108 113
109static struct platform_device scif4_device = { 114static struct platform_device scif4_device = {
@@ -121,6 +126,7 @@ static struct plat_sci_port scif5_platform_data = {
121 .scbrr_algo_id = SCBRR_ALGO_1, 126 .scbrr_algo_id = SCBRR_ALGO_1,
122 .type = PORT_SCIF, 127 .type = PORT_SCIF,
123 .irqs = { 53, 53, 53, 53 }, 128 .irqs = { 53, 53, 53, 53 },
129 .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
124}; 130};
125 131
126static struct platform_device scif5_device = { 132static struct platform_device scif5_device = {
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 3248ddaa889..14e1bae5039 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -117,6 +117,255 @@ to_sci_port(struct uart_port *uart)
117 return container_of(uart, struct sci_port, port); 117 return container_of(uart, struct sci_port, port);
118} 118}
119 119
120struct plat_sci_reg {
121 u8 offset, size;
122};
123
124/* Helper for invalidating specific entries of an inherited map. */
125#define sci_reg_invalid { .offset = 0, .size = 0 }
126
127static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
128 [SCIx_PROBE_REGTYPE] = {
129 [0 ... SCIx_NR_REGS - 1] = sci_reg_invalid,
130 },
131
132 /*
133 * Common SCI definitions, dependent on the port's regshift
134 * value.
135 */
136 [SCIx_SCI_REGTYPE] = {
137 [SCSMR] = { 0x00, 8 },
138 [SCBRR] = { 0x01, 8 },
139 [SCSCR] = { 0x02, 8 },
140 [SCxTDR] = { 0x03, 8 },
141 [SCxSR] = { 0x04, 8 },
142 [SCxRDR] = { 0x05, 8 },
143 [SCFCR] = sci_reg_invalid,
144 [SCFDR] = sci_reg_invalid,
145 [SCTFDR] = sci_reg_invalid,
146 [SCRFDR] = sci_reg_invalid,
147 [SCSPTR] = sci_reg_invalid,
148 [SCLSR] = sci_reg_invalid,
149 },
150
151 /*
152 * Common definitions for legacy IrDA ports, dependent on
153 * regshift value.
154 */
155 [SCIx_IRDA_REGTYPE] = {
156 [SCSMR] = { 0x00, 8 },
157 [SCBRR] = { 0x01, 8 },
158 [SCSCR] = { 0x02, 8 },
159 [SCxTDR] = { 0x03, 8 },
160 [SCxSR] = { 0x04, 8 },
161 [SCxRDR] = { 0x05, 8 },
162 [SCFCR] = { 0x06, 8 },
163 [SCFDR] = { 0x07, 16 },
164 [SCTFDR] = sci_reg_invalid,
165 [SCRFDR] = sci_reg_invalid,
166 [SCSPTR] = sci_reg_invalid,
167 [SCLSR] = sci_reg_invalid,
168 },
169
170 /*
171 * Common SCIFA definitions.
172 */
173 [SCIx_SCIFA_REGTYPE] = {
174 [SCSMR] = { 0x00, 16 },
175 [SCBRR] = { 0x04, 8 },
176 [SCSCR] = { 0x08, 16 },
177 [SCxTDR] = { 0x20, 8 },
178 [SCxSR] = { 0x14, 16 },
179 [SCxRDR] = { 0x24, 8 },
180 [SCFCR] = { 0x18, 16 },
181 [SCFDR] = { 0x1c, 16 },
182 [SCTFDR] = sci_reg_invalid,
183 [SCRFDR] = sci_reg_invalid,
184 [SCSPTR] = sci_reg_invalid,
185 [SCLSR] = sci_reg_invalid,
186 },
187
188 /*
189 * Common SCIFB definitions.
190 */
191 [SCIx_SCIFB_REGTYPE] = {
192 [SCSMR] = { 0x00, 16 },
193 [SCBRR] = { 0x04, 8 },
194 [SCSCR] = { 0x08, 16 },
195 [SCxTDR] = { 0x40, 8 },
196 [SCxSR] = { 0x14, 16 },
197 [SCxRDR] = { 0x60, 8 },
198 [SCFCR] = { 0x18, 16 },
199 [SCFDR] = { 0x1c, 16 },
200 [SCTFDR] = sci_reg_invalid,
201 [SCRFDR] = sci_reg_invalid,
202 [SCSPTR] = sci_reg_invalid,
203 [SCLSR] = sci_reg_invalid,
204 },
205
206 /*
207 * Common SH-3 SCIF definitions.
208 */
209 [SCIx_SH3_SCIF_REGTYPE] = {
210 [SCSMR] = { 0x00, 8 },
211 [SCBRR] = { 0x02, 8 },
212 [SCSCR] = { 0x04, 8 },
213 [SCxTDR] = { 0x06, 8 },
214 [SCxSR] = { 0x08, 16 },
215 [SCxRDR] = { 0x0a, 8 },
216 [SCFCR] = { 0x0c, 8 },
217 [SCFDR] = { 0x0e, 16 },
218 [SCTFDR] = sci_reg_invalid,
219 [SCRFDR] = sci_reg_invalid,
220 [SCSPTR] = sci_reg_invalid,
221 [SCLSR] = sci_reg_invalid,
222 },
223
224 /*
225 * Common SH-4(A) SCIF(B) definitions.
226 */
227 [SCIx_SH4_SCIF_REGTYPE] = {
228 [SCSMR] = { 0x00, 16 },
229 [SCBRR] = { 0x04, 8 },
230 [SCSCR] = { 0x08, 16 },
231 [SCxTDR] = { 0x0c, 8 },
232 [SCxSR] = { 0x10, 16 },
233 [SCxRDR] = { 0x14, 8 },
234 [SCFCR] = { 0x18, 16 },
235 [SCFDR] = { 0x1c, 16 },
236 [SCTFDR] = sci_reg_invalid,
237 [SCRFDR] = sci_reg_invalid,
238 [SCSPTR] = { 0x20, 16 },
239 [SCLSR] = { 0x24, 16 },
240 },
241
242 /*
243 * Common SH-4(A) SCIF(B) definitions for ports without an SCSPTR
244 * register.
245 */
246 [SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE] = {
247 [SCSMR] = { 0x00, 16 },
248 [SCBRR] = { 0x04, 8 },
249 [SCSCR] = { 0x08, 16 },
250 [SCxTDR] = { 0x0c, 8 },
251 [SCxSR] = { 0x10, 16 },
252 [SCxRDR] = { 0x14, 8 },
253 [SCFCR] = { 0x18, 16 },
254 [SCFDR] = { 0x1c, 16 },
255 [SCTFDR] = sci_reg_invalid,
256 [SCRFDR] = sci_reg_invalid,
257 [SCSPTR] = sci_reg_invalid,
258 [SCLSR] = { 0x24, 16 },
259 },
260
261 /*
262 * Common SH-4(A) SCIF(B) definitions for ports with FIFO data
263 * count registers.
264 */
265 [SCIx_SH4_SCIF_FIFODATA_REGTYPE] = {
266 [SCSMR] = { 0x00, 16 },
267 [SCBRR] = { 0x04, 8 },
268 [SCSCR] = { 0x08, 16 },
269 [SCxTDR] = { 0x0c, 8 },
270 [SCxSR] = { 0x10, 16 },
271 [SCxRDR] = { 0x14, 8 },
272 [SCFCR] = { 0x18, 16 },
273 [SCFDR] = { 0x1c, 16 },
274 [SCTFDR] = { 0x1c, 16 }, /* aliased to SCFDR */
275 [SCRFDR] = { 0x20, 16 },
276 [SCSPTR] = { 0x24, 16 },
277 [SCLSR] = { 0x28, 16 },
278 },
279
280 /*
281 * SH7705-style SCIF(B) ports, lacking both SCSPTR and SCLSR
282 * registers.
283 */
284 [SCIx_SH7705_SCIF_REGTYPE] = {
285 [SCSMR] = { 0x00, 16 },
286 [SCBRR] = { 0x04, 8 },
287 [SCSCR] = { 0x08, 16 },
288 [SCxTDR] = { 0x20, 8 },
289 [SCxSR] = { 0x14, 16 },
290 [SCxRDR] = { 0x24, 8 },
291 [SCFCR] = { 0x18, 16 },
292 [SCFDR] = { 0x1c, 16 },
293 [SCTFDR] = sci_reg_invalid,
294 [SCRFDR] = sci_reg_invalid,
295 [SCSPTR] = sci_reg_invalid,
296 [SCLSR] = sci_reg_invalid,
297 },
298};
299
300/*
301 * The "offset" here is rather misleading, in that it refers to an enum
302 * value relative to the port mapping rather than the fixed offset
303 * itself, which needs to be manually retrieved from the platform's
304 * register map for the given port.
305 */
306static unsigned int sci_serial_in(struct uart_port *p, int offset)
307{
308 struct sci_port *s = to_sci_port(p);
309 struct plat_sci_reg *reg = sci_regmap[s->cfg->regtype] + offset;
310
311 if (reg->size == 8)
312 return ioread8(p->membase + (reg->offset << p->regshift));
313 else if (reg->size == 16)
314 return ioread16(p->membase + (reg->offset << p->regshift));
315 else
316 WARN(1, "Invalid register access\n");
317
318 return 0;
319}
320
321static void sci_serial_out(struct uart_port *p, int offset, int value)
322{
323 struct sci_port *s = to_sci_port(p);
324 struct plat_sci_reg *reg = sci_regmap[s->cfg->regtype] + offset;
325
326 if (reg->size == 8)
327 iowrite8(value, p->membase + (reg->offset << p->regshift));
328 else if (reg->size == 16)
329 iowrite16(value, p->membase + (reg->offset << p->regshift));
330 else
331 WARN(1, "Invalid register access\n");
332}
333
334#define sci_in(up, offset) (up->serial_in(up, offset))
335#define sci_out(up, offset, value) (up->serial_out(up, offset, value))
336
337static int sci_probe_regmap(struct plat_sci_port *cfg)
338{
339 switch (cfg->type) {
340 case PORT_SCI:
341 cfg->regtype = SCIx_SCI_REGTYPE;
342 break;
343 case PORT_IRDA:
344 cfg->regtype = SCIx_IRDA_REGTYPE;
345 break;
346 case PORT_SCIFA:
347 cfg->regtype = SCIx_SCIFA_REGTYPE;
348 break;
349 case PORT_SCIFB:
350 cfg->regtype = SCIx_SCIFB_REGTYPE;
351 break;
352 case PORT_SCIF:
353 /*
354 * The SH-4 is a bit of a misnomer here, although that's
355 * where this particular port layout originated. This
356 * configuration (or some slight variation thereof)
357 * remains the dominant model for all SCIFs.
358 */
359 cfg->regtype = SCIx_SH4_SCIF_REGTYPE;
360 break;
361 default:
362 printk(KERN_ERR "Can't probe register map for given port\n");
363 return -EINVAL;
364 }
365
366 return 0;
367}
368
120#if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_SH_SCI_CONSOLE) 369#if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_SH_SCI_CONSOLE)
121 370
122#ifdef CONFIG_CONSOLE_POLL 371#ifdef CONFIG_CONSOLE_POLL
@@ -160,103 +409,29 @@ static void sci_poll_put_char(struct uart_port *port, unsigned char c)
160} 409}
161#endif /* CONFIG_CONSOLE_POLL || CONFIG_SERIAL_SH_SCI_CONSOLE */ 410#endif /* CONFIG_CONSOLE_POLL || CONFIG_SERIAL_SH_SCI_CONSOLE */
162 411
163#if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) 412static void sci_init_pins(struct uart_port *port, unsigned int cflag)
164static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
165{
166 if (port->mapbase == 0xA4400000) {
167 __raw_writew(__raw_readw(PACR) & 0xffc0, PACR);
168 __raw_writew(__raw_readw(PBCR) & 0x0fff, PBCR);
169 } else if (port->mapbase == 0xA4410000)
170 __raw_writew(__raw_readw(PBCR) & 0xf003, PBCR);
171}
172#elif defined(CONFIG_CPU_SUBTYPE_SH7720) || defined(CONFIG_CPU_SUBTYPE_SH7721)
173static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
174{
175 unsigned short data;
176
177 if (cflag & CRTSCTS) {
178 /* enable RTS/CTS */
179 if (port->mapbase == 0xa4430000) { /* SCIF0 */
180 /* Clear PTCR bit 9-2; enable all scif pins but sck */
181 data = __raw_readw(PORT_PTCR);
182 __raw_writew((data & 0xfc03), PORT_PTCR);
183 } else if (port->mapbase == 0xa4438000) { /* SCIF1 */
184 /* Clear PVCR bit 9-2 */
185 data = __raw_readw(PORT_PVCR);
186 __raw_writew((data & 0xfc03), PORT_PVCR);
187 }
188 } else {
189 if (port->mapbase == 0xa4430000) { /* SCIF0 */
190 /* Clear PTCR bit 5-2; enable only tx and rx */
191 data = __raw_readw(PORT_PTCR);
192 __raw_writew((data & 0xffc3), PORT_PTCR);
193 } else if (port->mapbase == 0xa4438000) { /* SCIF1 */
194 /* Clear PVCR bit 5-2 */
195 data = __raw_readw(PORT_PVCR);
196 __raw_writew((data & 0xffc3), PORT_PVCR);
197 }
198 }
199}
200#elif defined(CONFIG_CPU_SH3)
201/* For SH7705, SH7706, SH7707, SH7709, SH7709A, SH7729 */
202static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
203{ 413{
204 unsigned short data; 414 struct sci_port *s = to_sci_port(port);
205 415 struct plat_sci_reg *reg = sci_regmap[s->cfg->regtype] + SCSPTR;
206 /* We need to set SCPCR to enable RTS/CTS */
207 data = __raw_readw(SCPCR);
208 /* Clear out SCP7MD1,0, SCP6MD1,0, SCP4MD1,0*/
209 __raw_writew(data & 0x0fcf, SCPCR);
210
211 if (!(cflag & CRTSCTS)) {
212 /* We need to set SCPCR to enable RTS/CTS */
213 data = __raw_readw(SCPCR);
214 /* Clear out SCP7MD1,0, SCP4MD1,0,
215 Set SCP6MD1,0 = {01} (output) */
216 __raw_writew((data & 0x0fcf) | 0x1000, SCPCR);
217 416
218 data = __raw_readb(SCPDR); 417 /*
219 /* Set /RTS2 (bit6) = 0 */ 418 * Use port-specific handler if provided.
220 __raw_writeb(data & 0xbf, SCPDR); 419 */
420 if (s->cfg->ops && s->cfg->ops->init_pins) {
421 s->cfg->ops->init_pins(port, cflag);
422 return;
221 } 423 }
222}
223#elif defined(CONFIG_CPU_SUBTYPE_SH7722)
224static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
225{
226 unsigned short data;
227 424
228 if (port->mapbase == 0xffe00000) { 425 /*
229 data = __raw_readw(PSCR); 426 * For the generic path SCSPTR is necessary. Bail out if that's
230 data &= ~0x03cf; 427 * unavailable, too.
231 if (!(cflag & CRTSCTS)) 428 */
232 data |= 0x0340; 429 if (!reg->size)
430 return;
233 431
234 __raw_writew(data, PSCR);
235 }
236}
237#elif defined(CONFIG_CPU_SUBTYPE_SH7757) || \
238 defined(CONFIG_CPU_SUBTYPE_SH7763) || \
239 defined(CONFIG_CPU_SUBTYPE_SH7780) || \
240 defined(CONFIG_CPU_SUBTYPE_SH7785) || \
241 defined(CONFIG_CPU_SUBTYPE_SH7786) || \
242 defined(CONFIG_CPU_SUBTYPE_SHX3)
243static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
244{
245 if (!(cflag & CRTSCTS))
246 __raw_writew(0x0080, SCSPTR0); /* Set RTS = 1 */
247}
248#elif defined(CONFIG_CPU_SH4) && !defined(CONFIG_CPU_SH4A)
249static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
250{
251 if (!(cflag & CRTSCTS)) 432 if (!(cflag & CRTSCTS))
252 __raw_writew(0x0080, SCSPTR2); /* Set RTS = 1 */ 433 sci_out(port, SCSPTR, 0x0080); /* Set RTS = 1 */
253} 434}
254#else
255static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
256{
257 /* Nothing to do */
258}
259#endif
260 435
261#if defined(CONFIG_CPU_SUBTYPE_SH7760) || \ 436#if defined(CONFIG_CPU_SUBTYPE_SH7760) || \
262 defined(CONFIG_CPU_SUBTYPE_SH7780) || \ 437 defined(CONFIG_CPU_SUBTYPE_SH7780) || \
@@ -1752,6 +1927,9 @@ static int __devinit sci_init_single(struct platform_device *dev,
1752 break; 1927 break;
1753 } 1928 }
1754 1929
1930 if (p->regtype == SCIx_PROBE_REGTYPE)
1931 BUG_ON(sci_probe_regmap(p) != 0);
1932
1755 if (dev) { 1933 if (dev) {
1756 sci_port->iclk = clk_get(&dev->dev, "sci_ick"); 1934 sci_port->iclk = clk_get(&dev->dev, "sci_ick");
1757 if (IS_ERR(sci_port->iclk)) { 1935 if (IS_ERR(sci_port->iclk)) {
@@ -1812,9 +1990,10 @@ static int __devinit sci_init_single(struct platform_device *dev,
1812 port->mapbase = p->mapbase; 1990 port->mapbase = p->mapbase;
1813 port->type = p->type; 1991 port->type = p->type;
1814 port->flags = p->flags; 1992 port->flags = p->flags;
1993 port->regshift = p->regshift;
1815 1994
1816 /* 1995 /*
1817 * The UART port needs an IRQ value, so we peg this to the TX IRQ 1996 * The UART port needs an IRQ value, so we peg this to the RX IRQ
1818 * for the multi-IRQ ports, which is where we are primarily 1997 * for the multi-IRQ ports, which is where we are primarily
1819 * concerned with the shutdown path synchronization. 1998 * concerned with the shutdown path synchronization.
1820 * 1999 *
@@ -1822,6 +2001,9 @@ static int __devinit sci_init_single(struct platform_device *dev,
1822 */ 2001 */
1823 port->irq = p->irqs[SCIx_RXI_IRQ]; 2002 port->irq = p->irqs[SCIx_RXI_IRQ];
1824 2003
2004 port->serial_in = sci_serial_in;
2005 port->serial_out = sci_serial_out;
2006
1825 if (p->dma_dev) 2007 if (p->dma_dev)
1826 dev_dbg(port->dev, "DMA device %p, tx %d, rx %d\n", 2008 dev_dbg(port->dev, "DMA device %p, tx %d, rx %d\n",
1827 p->dma_dev, p->dma_slave_tx, p->dma_slave_rx); 2009 p->dma_dev, p->dma_slave_tx, p->dma_slave_rx);
diff --git a/drivers/tty/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h
index 5834f33d20f..26de640a9d0 100644
--- a/drivers/tty/serial/sh-sci.h
+++ b/drivers/tty/serial/sh-sci.h
@@ -3,69 +3,6 @@
3#include <linux/gpio.h> 3#include <linux/gpio.h>
4 4
5#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ 5#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
6 defined(CONFIG_CPU_SUBTYPE_SH7706) || \
7 defined(CONFIG_CPU_SUBTYPE_SH7707) || \
8 defined(CONFIG_CPU_SUBTYPE_SH7708) || \
9 defined(CONFIG_CPU_SUBTYPE_SH7709)
10# define SCPCR 0xA4000116 /* 16 bit SCI and SCIF */
11# define SCPDR 0xA4000136 /* 8 bit SCI and SCIF */
12#elif defined(CONFIG_CPU_SUBTYPE_SH7720) || \
13 defined(CONFIG_CPU_SUBTYPE_SH7721) || \
14 defined(CONFIG_ARCH_SH73A0) || \
15 defined(CONFIG_ARCH_SH7367) || \
16 defined(CONFIG_ARCH_SH7377) || \
17 defined(CONFIG_ARCH_SH7372)
18# define PORT_PTCR 0xA405011EUL
19# define PORT_PVCR 0xA4050122UL
20#elif defined(CONFIG_CPU_SUBTYPE_SH7750) || \
21 defined(CONFIG_CPU_SUBTYPE_SH7750R) || \
22 defined(CONFIG_CPU_SUBTYPE_SH7750S) || \
23 defined(CONFIG_CPU_SUBTYPE_SH7091) || \
24 defined(CONFIG_CPU_SUBTYPE_SH7751) || \
25 defined(CONFIG_CPU_SUBTYPE_SH7751R) || \
26 defined(CONFIG_CPU_SUBTYPE_SH4_202)
27# define SCSPTR2 0xFFE80020 /* 16 bit SCIF */
28#elif defined(CONFIG_CPU_SUBTYPE_SH7760)
29# define SCSPTR0 0xfe600024 /* 16 bit SCIF */
30# define SCSPTR2 0xfe620024 /* 16 bit SCIF */
31#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
32# define SCSPTR0 0xA4400000 /* 16 bit SCIF */
33# define PACR 0xa4050100
34# define PBCR 0xa4050102
35#elif defined(CONFIG_CPU_SUBTYPE_SH7343)
36# define SCSPTR0 0xffe00010 /* 16 bit SCIF */
37#elif defined(CONFIG_CPU_SUBTYPE_SH7722)
38# define PWDR 0xA4050166
39# define PSCR 0xA405011E
40#elif defined(CONFIG_CPU_SUBTYPE_SH7366)
41# define SCPDR0 0xA405013E /* 16 bit SCIF0 PSDR */
42# define SCSPTR0 SCPDR0
43#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
44# define SCSPTR0 0xa4050160
45#elif defined(CONFIG_CPU_SUBTYPE_SH7757)
46# define SCSPTR0 0xfe4b0020
47#elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \
48 defined(CONFIG_CPU_SUBTYPE_SH7780)
49# define SCSPTR0 0xffe00024 /* 16 bit SCIF */
50#elif defined(CONFIG_CPU_SUBTYPE_SH7770)
51# define SCSPTR0 0xff923020 /* 16 bit SCIF */
52#elif defined(CONFIG_CPU_SUBTYPE_SH7785) || \
53 defined(CONFIG_CPU_SUBTYPE_SH7786)
54# define SCSPTR0 0xffea0024 /* 16 bit SCIF */
55#elif defined(CONFIG_CPU_SUBTYPE_SH7201) || \
56 defined(CONFIG_CPU_SUBTYPE_SH7203) || \
57 defined(CONFIG_CPU_SUBTYPE_SH7206) || \
58 defined(CONFIG_CPU_SUBTYPE_SH7263)
59# define SCSPTR0 0xfffe8020 /* 16 bit SCIF */
60#elif defined(CONFIG_CPU_SUBTYPE_SH7619)
61# define SCSPTR0 0xf8400020 /* 16 bit SCIF */
62#elif defined(CONFIG_CPU_SUBTYPE_SHX3)
63# define SCSPTR0 0xffc30020 /* 16 bit SCIF */
64#else
65# error CPU subtype not defined
66#endif
67
68#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
69 defined(CONFIG_CPU_SUBTYPE_SH7720) || \ 6 defined(CONFIG_CPU_SUBTYPE_SH7720) || \
70 defined(CONFIG_CPU_SUBTYPE_SH7721) || \ 7 defined(CONFIG_CPU_SUBTYPE_SH7721) || \
71 defined(CONFIG_ARCH_SH73A0) || \ 8 defined(CONFIG_ARCH_SH73A0) || \
@@ -119,162 +56,3 @@
119 56
120#define SCI_MAJOR 204 57#define SCI_MAJOR 204
121#define SCI_MINOR_START 8 58#define SCI_MINOR_START 8
122
123#define SCI_IN(size, offset) \
124 ioread##size(port->membase + (offset))
125
126#define SCI_OUT(size, offset, value) \
127 iowrite##size(value, port->membase + (offset))
128
129#define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\
130 static inline unsigned int sci_##name##_in(struct uart_port *port) \
131 { \
132 if (port->type == PORT_SCIF || port->type == PORT_SCIFB) { \
133 return SCI_IN(scif_size, scif_offset); \
134 } else { /* PORT_SCI or PORT_SCIFA */ \
135 return SCI_IN(sci_size, sci_offset); \
136 } \
137 } \
138 static inline void sci_##name##_out(struct uart_port *port, unsigned int value) \
139 { \
140 if (port->type == PORT_SCIF || port->type == PORT_SCIFB) { \
141 SCI_OUT(scif_size, scif_offset, value); \
142 } else { /* PORT_SCI or PORT_SCIFA */ \
143 SCI_OUT(sci_size, sci_offset, value); \
144 } \
145 }
146
147#define CPU_SCIF_FNS(name, scif_offset, scif_size) \
148 static inline unsigned int sci_##name##_in(struct uart_port *port) \
149 { \
150 return SCI_IN(scif_size, scif_offset); \
151 } \
152 static inline void sci_##name##_out(struct uart_port *port, unsigned int value) \
153 { \
154 SCI_OUT(scif_size, scif_offset, value); \
155 }
156
157#if defined(CONFIG_CPU_SH3) || \
158 defined(CONFIG_ARCH_SH73A0) || \
159 defined(CONFIG_ARCH_SH7367) || \
160 defined(CONFIG_ARCH_SH7377) || \
161 defined(CONFIG_ARCH_SH7372)
162#if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
163#define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \
164 sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \
165 CPU_SCIx_FNS(name, sh4_sci_offset, sh4_sci_size, sh4_scif_offset, sh4_scif_size)
166#define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \
167 CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size)
168#elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \
169 defined(CONFIG_CPU_SUBTYPE_SH7720) || \
170 defined(CONFIG_CPU_SUBTYPE_SH7721) || \
171 defined(CONFIG_ARCH_SH7367)
172#define SCIF_FNS(name, scif_offset, scif_size) \
173 CPU_SCIF_FNS(name, scif_offset, scif_size)
174#elif defined(CONFIG_ARCH_SH7377) || \
175 defined(CONFIG_ARCH_SH7372) || \
176 defined(CONFIG_ARCH_SH73A0)
177#define SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scifb_offset, sh4_scifb_size) \
178 CPU_SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scifb_offset, sh4_scifb_size)
179#define SCIF_FNS(name, scif_offset, scif_size) \
180 CPU_SCIF_FNS(name, scif_offset, scif_size)
181#else
182#define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \
183 sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \
184 CPU_SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh3_scif_offset, sh3_scif_size)
185#define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \
186 CPU_SCIF_FNS(name, sh3_scif_offset, sh3_scif_size)
187#endif
188#elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\
189 defined(CONFIG_CPU_SUBTYPE_SH7724)
190 #define SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scif_offset, sh4_scif_size) \
191 CPU_SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scif_offset, sh4_scif_size)
192 #define SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) \
193 CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size)
194#else
195#define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \
196 sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \
197 CPU_SCIx_FNS(name, sh4_sci_offset, sh4_sci_size, sh4_scif_offset, sh4_scif_size)
198#define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \
199 CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size)
200#endif
201
202#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
203 defined(CONFIG_CPU_SUBTYPE_SH7720) || \
204 defined(CONFIG_CPU_SUBTYPE_SH7721) || \
205 defined(CONFIG_ARCH_SH7367)
206
207SCIF_FNS(SCSMR, 0x00, 16)
208SCIF_FNS(SCBRR, 0x04, 8)
209SCIF_FNS(SCSCR, 0x08, 16)
210SCIF_FNS(SCxSR, 0x14, 16)
211SCIF_FNS(SCFCR, 0x18, 16)
212SCIF_FNS(SCFDR, 0x1c, 16)
213SCIF_FNS(SCxTDR, 0x20, 8)
214SCIF_FNS(SCxRDR, 0x24, 8)
215SCIF_FNS(SCLSR, 0x00, 0)
216#elif defined(CONFIG_ARCH_SH7377) || \
217 defined(CONFIG_ARCH_SH7372) || \
218 defined(CONFIG_ARCH_SH73A0)
219SCIF_FNS(SCSMR, 0x00, 16)
220SCIF_FNS(SCBRR, 0x04, 8)
221SCIF_FNS(SCSCR, 0x08, 16)
222SCIF_FNS(SCTDSR, 0x0c, 16)
223SCIF_FNS(SCFER, 0x10, 16)
224SCIF_FNS(SCxSR, 0x14, 16)
225SCIF_FNS(SCFCR, 0x18, 16)
226SCIF_FNS(SCFDR, 0x1c, 16)
227SCIF_FNS(SCTFDR, 0x38, 16)
228SCIF_FNS(SCRFDR, 0x3c, 16)
229SCIx_FNS(SCxTDR, 0x20, 8, 0x40, 8)
230SCIx_FNS(SCxRDR, 0x24, 8, 0x60, 8)
231SCIF_FNS(SCLSR, 0x00, 0)
232#elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\
233 defined(CONFIG_CPU_SUBTYPE_SH7724)
234SCIx_FNS(SCSMR, 0x00, 16, 0x00, 16)
235SCIx_FNS(SCBRR, 0x04, 8, 0x04, 8)
236SCIx_FNS(SCSCR, 0x08, 16, 0x08, 16)
237SCIx_FNS(SCxTDR, 0x20, 8, 0x0c, 8)
238SCIx_FNS(SCxSR, 0x14, 16, 0x10, 16)
239SCIx_FNS(SCxRDR, 0x24, 8, 0x14, 8)
240SCIx_FNS(SCSPTR, 0, 0, 0, 0)
241SCIF_FNS(SCFCR, 0x18, 16)
242SCIF_FNS(SCFDR, 0x1c, 16)
243SCIF_FNS(SCLSR, 0x24, 16)
244#else
245/* reg SCI/SH3 SCI/SH4 SCIF/SH3 SCIF/SH4 */
246/* name off sz off sz off sz off sz */
247SCIx_FNS(SCSMR, 0x00, 8, 0x00, 8, 0x00, 8, 0x00, 16)
248SCIx_FNS(SCBRR, 0x02, 8, 0x04, 8, 0x02, 8, 0x04, 8)
249SCIx_FNS(SCSCR, 0x04, 8, 0x08, 8, 0x04, 8, 0x08, 16)
250SCIx_FNS(SCxTDR, 0x06, 8, 0x0c, 8, 0x06, 8, 0x0C, 8)
251SCIx_FNS(SCxSR, 0x08, 8, 0x10, 8, 0x08, 16, 0x10, 16)
252SCIx_FNS(SCxRDR, 0x0a, 8, 0x14, 8, 0x0A, 8, 0x14, 8)
253SCIF_FNS(SCFCR, 0x0c, 8, 0x18, 16)
254#if defined(CONFIG_CPU_SUBTYPE_SH7760) || \
255 defined(CONFIG_CPU_SUBTYPE_SH7780) || \
256 defined(CONFIG_CPU_SUBTYPE_SH7785) || \
257 defined(CONFIG_CPU_SUBTYPE_SH7786)
258SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16)
259SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16)
260SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16)
261SCIF_FNS(SCSPTR, 0, 0, 0x24, 16)
262SCIF_FNS(SCLSR, 0, 0, 0x28, 16)
263#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
264SCIF_FNS(SCFDR, 0, 0, 0x1C, 16)
265SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16)
266SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16)
267SCIF_FNS(SCSPTR, 0, 0, 0x24, 16)
268SCIF_FNS(SCLSR, 0, 0, 0x28, 16)
269#else
270SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16)
271#if defined(CONFIG_CPU_SUBTYPE_SH7722)
272SCIF_FNS(SCSPTR, 0, 0, 0, 0)
273#else
274SCIF_FNS(SCSPTR, 0, 0, 0x20, 16)
275#endif
276SCIF_FNS(SCLSR, 0, 0, 0x24, 16)
277#endif
278#endif
279#define sci_in(port, reg) sci_##reg##_in(port)
280#define sci_out(port, reg, value) sci_##reg##_out(port, value)
diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h
index ecefec7c0b6..4ca130a90ea 100644
--- a/include/linux/serial_sci.h
+++ b/include/linux/serial_sci.h
@@ -58,6 +58,22 @@ enum {
58 SCIx_NR_IRQS, 58 SCIx_NR_IRQS,
59}; 59};
60 60
61enum {
62 SCIx_PROBE_REGTYPE,
63
64 SCIx_SCI_REGTYPE,
65 SCIx_IRDA_REGTYPE,
66 SCIx_SCIFA_REGTYPE,
67 SCIx_SCIFB_REGTYPE,
68 SCIx_SH3_SCIF_REGTYPE,
69 SCIx_SH4_SCIF_REGTYPE,
70 SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
71 SCIx_SH4_SCIF_FIFODATA_REGTYPE,
72 SCIx_SH7705_SCIF_REGTYPE,
73
74 SCIx_NR_REGTYPES,
75};
76
61#define SCIx_IRQ_MUXED(irq) \ 77#define SCIx_IRQ_MUXED(irq) \
62{ \ 78{ \
63 [SCIx_ERI_IRQ] = (irq), \ 79 [SCIx_ERI_IRQ] = (irq), \
@@ -66,8 +82,24 @@ enum {
66 [SCIx_BRI_IRQ] = (irq), \ 82 [SCIx_BRI_IRQ] = (irq), \
67} 83}
68 84
85/*
86 * SCI register subset common for all port types.
87 * Not all registers will exist on all parts.
88 */
89enum {
90 SCSMR, SCBRR, SCSCR, SCxSR,
91 SCFCR, SCFDR, SCxTDR, SCxRDR,
92 SCLSR, SCTFDR, SCRFDR, SCSPTR,
93
94 SCIx_NR_REGS,
95};
96
69struct device; 97struct device;
70 98
99struct plat_sci_port_ops {
100 void (*init_pins)(struct uart_port *, unsigned int cflag);
101};
102
71/* 103/*
72 * Platform device specific platform_data struct 104 * Platform device specific platform_data struct
73 */ 105 */
@@ -87,6 +119,10 @@ struct plat_sci_port {
87 unsigned int error_mask; 119 unsigned int error_mask;
88 120
89 int port_reg; 121 int port_reg;
122 unsigned char regshift;
123 unsigned char regtype;
124
125 struct plat_sci_port_ops *ops;
90 126
91 struct device *dma_dev; 127 struct device *dma_dev;
92 128